Reputation: 255
I am a novice and learning about dictionaries in python, and spent better part of a day wrapping my head around it, I would appreciate some help!
I would like to create a dictionary of dictionaries:
data = [['dog', 'a'], ['mouse', 'a'], ['dog', 'b'], ['mouse', 'c'], ['dog', 'c']]
animals = ['dog', 'mouse']
I would like to do this:
final = {'dog': {'a': 0, 'b': 0, 'c': 0}, 'mouse':{'a': 0, 'c': 0} }
So far I have this code, which obviously is not working:
animal_dict = {}
for d in data:
animal_dict[d[0]] = {}
letter_dict = {}
for animal in animal_dict:
for d in data:
if d[0] == animal:
letter_dict[d[1]] = 0
animal_dict[animal] = letter_dict
print animal_dict
Notice that it is adding an extra key ('b') in the 'mouse' dictionary. I know I am making it more complicated than it should be! Thanks in advance for helping a novice.
Upvotes: 2
Views: 130
Reputation: 298216
You only really need one loop:
data = [['dog', 'a'], ['mouse', 'a'], ['dog', 'b'], ['mouse', 'c'], ['dog', 'c']]
animals = {}
for animal, letter in data:
animals.setdefault(animal, {})[letter] = 0
Or if you don't like setdefault
:
for animal, letter in data:
if animal in animals:
animals[animal][letter] = 0
else:
animals[animal] = {letter: 0}
Or with defaultdict
:
from collections import defaultdict:
animals = defaultdict(dict) # creates a dict when the key doesn't exist
for animal, letter in data:
animals.[animal][letter] = 0
Upvotes: 4
Reputation: 706
Quick and dirty, the animals list is unnecessary really.
d = {}
for animal, letter in data:
if not d.has_key(animal):
d[animal] = {}
if not d[animal].has_key(letter):
d[animal][letter] = 0
Upvotes: 0
Reputation: 716
Don't you love how many different ways there are to do things in Python? :-)
You can also just move creation of letter_dict inside the outer loop:
for animal in animal_dict:
letter_dict = {} # Create new letter_dict for each animal
for d in data:
if d[0] == animal:
letter_dict[d[1]] = 0
animal_dict[animal] = letter_dict
Upvotes: 0
Reputation: 3985
You are using the same dict
when adding it to the animal_dict
hence why there is an extra b key. You should check if the animal in animal_dict
and if it isn't then add the new key with a empty dict.
for animal in animal_dict:
if not animal in animal_dict:
animal_dict[animal] = {}
for d in data:
if d[0] == animal:
animal_dict[animal][d[1]] = letter_dict
Another option is to use a defaultdict documentation. That would remove the need for the key check in the loop.
Upvotes: 0
Reputation: 59984
>>> d = {}
>>> for i in data:
... if i[0] not in d:
... d[i[0]] = {i[1] : 0}
... else:
... d[i[0]][i[1]] = 0
...
>>> d
{'mouse': {'a': 0, 'c': 0}, 'dog': {'a': 0, 'c': 0, 'b': 0}}
You're using the same dictionary to put both the dog and mouse values in, hence the extra 'b' key, because there would already be a 'b' from the dog. You could create an if/else
statement to differentiate each.
Upvotes: 0
Reputation: 23575
You are setting both animal_dict['dog']
and animal_dict['mouse']
to the same letter_dict
object. Any keys you add to one will be added to the other.
You do not actually need letter_dict
. Try this instead:
for animal in animal_dict:
for d in data:
if d[0] == animal:
animal_dict[animal][d[1]] = 0
Upvotes: 1