Reputation: 636
I'm trying to build a matrix that holds several values in several levels. I'm trying to generate a dictionary build up like this:
{'routername':{'channel':{'01':<value>,'02':<value>}}}
The number of keys on the highest level may vary.
The script is generating a list of available routers and another list of available channels. I wrote a rather cumbersome function that test for a key and if it is not already there, it adds the key to the dictionary.
So, I was wondering if there isn't an easy way to create a dictionary with empty values for the keys in list 'routers'
def AddToChart(passed_seq):
try:
if str(passed_seq[0]) in chart_dict:
if str(passed_seq[1]) in chart_dict[passed_seq[0]]:
if str(passed_seq[2]) in chart_dict[passed_seq[0]][passed_seq[1]]:
if str(passed_seq[3]) in chart_dict[passed_seq[0]][passed_seq[1]][passed_seq[2]]:
chart_dict[passed_seq[0]][passed_seq[1]][passed_seq[2]][passed_seq[3]].update(err_sub_dict)
else:
chart_dict[passed_seq[0]][passed_seq[1]][passed_seq[2]].update({passed_seq[3]:{}})
chart_dict[passed_seq[0]][passed_seq[1]][passed_seq[2]][passed_seq[3]].update(err_sub_dict)
else:
chart_dict[passed_seq[0]][passed_seq[1]].update({passed_seq[2]:{passed_seq[3]:{}}})
chart_dict[passed_seq[0]][passed_seq[1]][passed_seq[2]][passed_seq[3]].update(err_sub_dict)
else:
chart_dict[passed_seq[0]].update({passed_seq[1]:{passed_seq[2]:{passed_seq[3]:{}}}})
chart_dict[passed_seq[0]][passed_seq[1]][passed_seq[2]][passed_seq[3]].update(err_sub_dict)
else:
chart_dict.update({passed_seq[0]:{passed_seq[1]:{passed_seq[2]:{passed_seq[3]:{}}}}})
chart_dict[passed_seq[0]][passed_seq[1]][passed_seq[2]][passed_seq[3]].update(err_sub_dict)
except ValueError:
print "AddToChart: ",err_sub_dict,sys.exc_info()[1][0]
except:
print sys.exc_info()
print "AddToChart: variable not defined: " + str(passed_seq)
Upvotes: 1
Views: 141
Reputation: 104712
I suggest using a nested collections.defaultdict
for chart_dict
. It lets you provide a factory function to set up new values, so any key you request will always work. It's a little tricky to get such a deeply nested structure set up, but I think the following will do the right thing for your four-level structure (I'm assuming your <value>
items are also dictionaries, as it seems your current code expects):
chart_dict = defaultdict(lambda:defaultdict(lambda:defaultdict(dict)))
With that in place, you should then be able to do the following without worrying about whether any of the keys previously referenced anything in the dictionary:
a, b, c = passed_seq
chart_dict[a][b][c].update(err_sub_dict)
I'd suggest doing something like the variable unpacking above too, though you should probably use better names than a
, b
, and c
. Good variable names can turn something incomprehensible into something easy to grasp.
Upvotes: 1
Reputation: 1790
You should use
dict.setdefault()
See docs.
Example:
d = {}
d = d.setdefault("k","eggs")
>> d["k"]
eggs
d2 = {"k":1}
d2 = d2.setdefault("k","spam")
>> d2["k"]
1
Upvotes: 1