Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multi-level defaultdict with variable depth?

I have a large list like:

[A][B1][C1]=1 [A][B1][C2]=2 [A][B2]=3 [D][E][F][G]=4 

I want to build a multi-level dict like:

A --B1 -----C1=1 -----C2=1 --B2=3 D --E ----F ------G=4 

I know that if I use recursive defaultdict I can write table[A][B1][C1]=1, table[A][B2]=2, but this works only if I hardcode those insert statement.

While parsing the list, I don't how many []'s I need beforehand to call table[key1][key2][...].

like image 1000
Wei Shi Avatar asked Mar 20 '11 16:03

Wei Shi


People also ask

Is Defaultdict faster than dict?

Finally, using a defaultdict to handle missing keys can be faster than using dict.

Can you nest Defaultdict?

Now that we understand nested dictionaries and defaultdicts , we can get into nested defaultdicts . This is concept is extremely powerful as it allows you to build complex dictionaries with a simple initialization. The only caveat is that you need to know the depth of your data structure in advance.

What is the difference between Defaultdict and dict?

The difference is that a defaultdict will "default" a value if that key has not been set yet. If you didn't use a defaultdict you'd have to check to see if that key exists, and if it doesn't, set it to what you want. The lambda is defining a factory for the default value.

What is Lambda Defaultdict?

defaultdict takes a zero-argument callable to its constructor, which is called when the key is not found, as you correctly explained. lambda: 0 will of course always return zero, but the preferred method to do that is defaultdict(int) , which will do the same thing.


2 Answers

You can do it without even defining a class:

from collections import defaultdict  nested_dict = lambda: defaultdict(nested_dict) nest = nested_dict()  nest[0][1][2][3][4][5] = 6 
like image 178
Hugo Walter Avatar answered Oct 04 '22 16:10

Hugo Walter


Your example says that at any level there can be a value, and also a dictionary of sub-elements. That is called a tree, and there are many implementations available for them. This is one:

from collections import defaultdict class Tree(defaultdict):     def __init__(self, value=None):         super(Tree, self).__init__(Tree)         self.value = value  root = Tree() root.value = 1 root['a']['b'].value = 3 print root.value print root['a']['b'].value print root['c']['d']['f'].value 

Outputs:

1 3 None 

You could do something similar by writing the input in JSON and using json.load to read it as a structure of nested dictionaries.

like image 25
Apalala Avatar answered Oct 04 '22 14:10

Apalala