pythonpython-2.7dictionaryrenpy

Initialize a new dictionary from a tuple and the keys of another dictionary


I'm trying to build a dictionary using keys that come from [the values of] a tuple, and the value of those keys should be a new dictionary formed from the keys of a dictionary and the value of the sub-key initialized to 0.

The tuple looks like:

characters = ('Fred', 'Sam', 'Bob', 'Daisy', 'Gina', 'Rupert')

The dictionary involved looks like:

jobs = {
    'Pizzeria': 1,
    'Mall Kiosk': 2
    'Restaurant': 3
    'Burger Joint': 4
    'Department Store': 5
}

I'd like the final structure to look like:

jobsWorkedCounter = {
    'Fred': {
        'Pizzeria': 0,
        'Mall Kiosk': 0
        'Restaurant': 0
        'Burger Joint': 0
        'Department Store': 0
    },
    'Sam': {
        'Pizzeria': 0,
        'Mall Kiosk': 0
        'Restaurant': 0
        'Burger Joint': 0
        'Department Store': 0
    },

    ...

    'Rupert': {
        'Pizzeria': 0,
        'Mall Kiosk': 0
        'Restaurant': 0
        'Burger Joint': 0
        'Department Store': 0
    },
}

The end goal is to have a structure for incrementing counters:

jobsWorkedCounter['Fred']['Burger Joint'] += 1

I've tried using various nested comprehensions:

jobsWorkedCounter = { char: dict((key, 0) for key in jobs.keys()) for char in characters }

# and

jobsWorkedCounter = { char: dict(jobs.keys(), 0) for char in characters }

# and

jobsWorkedCounterDict = { key: 0 for key in jobs.keys() }
jobsWorkedCounter = { char: jobsWorkedCounterDict for char in characters }

# and

jobsWorkedCounter = { char: { key: 0 for key in jobs.keys() } for char in characters }

and a simple for loop:

jobsWorkedCounter = { char: {} for char in characters }
    for char in characters:
        jobsWorkedCounter[char] = dict.fromkeys(jobs.keys(), 0)

but the best I've been able to accomplish is a single sub-key instead of the full set:

jobsWorkedCounter = {
    'Fred': {
        'Pizzeria': 0,
    },
    'Sam': {
        'Pizzeria': 0,
    },

    ...

    'Rupert': {
        'Pizzeria': 0,
    },
}

It seems that no matter what I try, I'm managing to flatten the new dictionary down to a single key-value pair and that's what gets assigned to the key from the tuple.

How can I accomplish what I'm trying to do?

Also, just in case I'm doing this incorrectly as well, to check the output I'm doing this:

keys = jobsWorkedCounter['Fred'].keys()
raise Exception(keys)

which gets me:

Exception: [u'Pizzeria']

where I would expect to see:

Exception: [u'Pizzeria', u'Mall Kiosk', u'Restaurant', u'Burger Joint', u'Department Store']  

I'm fairly sure this method of seeing the keys should work because if I change it to:

keys = jobsWorkedCounter.keys()
raise Exception(keys)

I get:

Exception: [u'Fred', u'Sam', u'Bob', u'Daisy', u'Gina', u'Rupert']

Addendum

I'm stuck using Python 2.7 as I'm in a Ren'Py environment (hence the reason for raising an exception to see the output).

For example:

from pprint import pprint

gives me:

Import Error: No module named pprint

Solution

  • I created a new Ren'Py project (from Ubuntu 18.04) and added the following code at the beginning of screens.rpy. This is basically one of your tentatives:

    init python:
        characters = ('Fred', 'Sam', 'Bob', 'Daisy', 'Gina', 'Rupert')
    
        jobs = {
            'Pizzeria': 1,
            'Mall Kiosk': 2,
            'Restaurant': 3,
            'Burger Joint': 4,
            'Department Store': 5
        }
    
        jobsWorkedCounter = {char: {key: 0 for key in jobs.keys()} for char in characters}
        keys = jobsWorkedCounter['Fred'].keys()
        raise Exception(keys)
    

    And I get:

    I'm sorry, but an uncaught exception occurred.
    
    While running game code:
      File "game/screens.rpy", line 5, in script
        init python:
      File "game/screens.rpy", line 19, in <module>
        raise Exception(keys)
    Exception: [u'Department Store', u'Pizzeria', u'Restaurant', u'Mall Kiosk', u'Burger Joint']
    
    -- Full Traceback ------------------------------------------------------------
    
    Full traceback:
      File "game/screens.rpy", line 5, in script
        init python:
      File "/usr/share/games/renpy/renpy/ast.py", line 848, in execute
        renpy.python.py_exec_bytecode(self.code.bytecode, self.hide, store=self.store)
      File "/usr/share/games/renpy/renpy/python.py", line 1812, in py_exec_bytecode
        exec bytecode in globals, locals
      File "game/screens.rpy", line 19, in <module>
        raise Exception(keys)
    Exception: [u'Department Store', u'Pizzeria', u'Restaurant', u'Mall Kiosk', u'Burger Joint']
    
    Linux-4.15.0-55-generic-x86_64-with-Ubuntu-18.04-bionic
    Ren'Py 6.99.14.1.3218
    test_renpy 1.0
    Wed Jul 24 21:03:28 2019
    

    so, I would tend to think you have a bug somewhere else in your code.