I have a long list of nested tuples that I am iterating through and appending in a certain way such that an empty dictionary:
dict = {}
will be filled like this:
dict = {a: {b:1,5,9,2,3}, b: {c:7,4,5,6,2,4}, c: {b:3,13,2,4,2}... }
The iteration will check if a nested dictionary exists, and if so, then it will append the value, otherwise, create a nested dictionary. My poor attempt looks something like this:
longlist = [(1,(a,b)),(2,(b,c)), (3,(c,b)) ... ]
dict = {}
for each in longlist:
if dict[each[1][0]][each[1][1]]:
dict[each[1][0]][each[1][1]].append(each[0])
else:
dict[each[1][0]] = {}
dict[each[1][0]][each[1][1]] = each[0]
The problem with my approach is that the iteration fails because the dictionary is empty to begin with or that the parent of the nest doesn't exist in dict. It's getting complicated for me. I wasn't able to find much info online on how to tackle nested dictionaries, so I thought it should be okay to ask here.
Here is a solution using
collections.defaultdict
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
Also not the for line vs "for each ..." This is unpacking the items in the iterable. You could also have done
but since keys is an iterable as well, you can unpack it as well if you wrap it in parens.
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: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?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:Full listing:
This is much more readable than before.