Populating A Nested Dictionary
Solution 1:
Here is a solution using collections.defaultdict
import random
import collections
choices = ['a', 'b', 'c', 'd', 'e', 'f']
longlist = []
for i in range(1, 101):
longlist.append((i, tuple(random.sample(choices, 2))))
print longlist
final = collections.defaultdict(lambda: collections.defaultdict(list))
for value, (key1, key2) in longlist:
final[key1][key2].append(value)
print final
In general, the way that I would change your code would be to first ensure the nested dictionaries exist (collections.defaultdict takes care of this for you) and then always append once.
Something like
for value (key1, key2) in longlist:
if not your_dict.get(key1):
your_dict[key1] = {}
if not your_dict.get(key1).get(key2):
your_dict[key1][key2] = []
your_dict[key1][key2].append(value)
Also not the for line vs "for each ..." This is unpacking the items in the iterable. You could also have done
for value, keys in longlist:
but since keys is an iterable as well, you can unpack it as well if you wrap it in parens.
Solution 2:
Without delving much into what you are trying to do, you can rewrite your if
statement to not throw an error if the keys do not exist:
if dict_.get(each[1][0], {}).get(each[1][1], None):
dict_[each[1][0]][each[1][1]].append(each[0])
The dict.get
is an extremely useful function in that it returns a certain default value if the given key does not exist.
Also, it seems you expect a list to exist. In the else
block, did you mean to do this?
dict_[each[1][0]][each[1][1]] = [each[0]]
This will create a list with a single element, so now dict[...][...].append(...)
will work.
I also recommend not using dict
to name your variable. It shadows the inbuilt class.
Further improvements might include unpacking items in the head of the for loop, so you don't have to do each[0]
, each[1]
, and so on. You could use something like:
for idx, pair in longlist:
x, y = pair # unpack each pair now
...
Full listing:
dict_ = {}
for idx, pair in longlist:
x, y = pair
if dict_.get(x, {}).get(y, None):
dict_[x][y].append(idx)
else:
dict_[x] = {y : [idx] }
This is much more readable than before.
Post a Comment for "Populating A Nested Dictionary"