Reputation: 25091
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']
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
Upvotes: 0
Views: 2175
Reputation: 26906
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.
Upvotes: 1
Reputation: 195553
Using dict comprehensions:
characters = ('Fred', 'Sam', 'Bob', 'Daisy', 'Gina', 'Rupert')
jobs = {
'Pizzeria': 1,
'Mall Kiosk': 2,
'Restaurant': 3,
'Burger Joint': 4,
'Department Store': 5
}
jobsWorkedCounter = {c: {k: 0 for k in jobs} for c in characters}
# For pretty print:
#from pprint import pprint
#pprint(jobsWorkedCounter)
print(jobsWorkedCounter)
Prints:
{'Bob': {'Burger Joint': 0,
'Department Store': 0,
'Mall Kiosk': 0,
'Pizzeria': 0,
'Restaurant': 0},
'Daisy': {'Burger Joint': 0,
'Department Store': 0,
'Mall Kiosk': 0,
'Pizzeria': 0,
'Restaurant': 0},
'Fred': {'Burger Joint': 0,
'Department Store': 0,
'Mall Kiosk': 0,
'Pizzeria': 0,
'Restaurant': 0},
'Gina': {'Burger Joint': 0,
'Department Store': 0,
'Mall Kiosk': 0,
'Pizzeria': 0,
'Restaurant': 0},
'Rupert': {'Burger Joint': 0,
'Department Store': 0,
'Mall Kiosk': 0,
'Pizzeria': 0,
'Restaurant': 0},
'Sam': {'Burger Joint': 0,
'Department Store': 0,
'Mall Kiosk': 0,
'Pizzeria': 0,
'Restaurant': 0}}
EDIT: Another, explicit version:
zeroed_jobs = dict((k, 0) for k in jobs)
jobsWorkedCounter = {c: dict(**zeroed_jobs) for c in characters}
print(jobsWorkedCounter)
Upvotes: 1