I have a data structure which essentially amounts to a nested dictionary. Let's say it looks like this:
{'new jersey': {'mercer county': {'plumbers': 3,
'programmers': 81},
'middlesex county': {'programmers': 81,
'salesmen': 62}},
'new york': {'queens county': {'plumbers': 9,
'salesmen': 36}}}
Now, maintaining and creating this is pretty painful; every time I have a new state/county/profession I have to create the lower layer dictionaries via obnoxious try/catch blocks. Moreover, I have to create annoying nested iterators if I want to go over all the values.
I could also use tuples as keys, like such:
{('new jersey', 'mercer county', 'plumbers'): 3,
('new jersey', 'mercer county', 'programmers'): 81,
('new jersey', 'middlesex county', 'programmers'): 81,
('new jersey', 'middlesex county', 'salesmen'): 62,
('new york', 'queens county', 'plumbers'): 9,
('new york', 'queens county', 'salesmen'): 36}
This makes iterating over the values very simple and natural, but it is more syntactically painful to do things like aggregations and looking at subsets of the dictionary (e.g. if I just want to go state-by-state).
Basically, sometimes I want to think of a nested dictionary as a flat dictionary, and sometimes I want to think of it indeed as a complex hierarchy. I could wrap this all in a class, but it seems like someone might have done this already. Alternatively, it seems like there might be some really elegant syntactical constructions to do this.
How could I do this better?
Addendum: I'm aware of setdefault()
but it doesn't really make for clean syntax. Also, each sub-dictionary you create still needs to have setdefault()
manually set.
You can use recursion in lambdas and defaultdict, no need to define names:
Here's an example:
This is a function that returns a nested dictionary of arbitrary depth:
Use it like this:
Iterate through everything with something like this:
This prints out:
You might eventually want to make it so that new items can not be added to the dict. It's easy to recursively convert all these
defaultdict
s to normaldict
s.I find
setdefault
quite useful; It checks if a key is present and adds it if not:setdefault
always returns the relevant key, so you are actually updating the values of 'd
' in place.When it comes to iterating, I'm sure you could write a generator easily enough if one doesn't already exist in Python:
As others have suggested, a relational database could be more useful to you. You can use a in-memory sqlite3 database as a data structure to create tables and then query them.
This is just a simple example. You could define separate tables for states, counties and job titles.
You can use Addict: https://github.com/mewwts/addict
Example:
Edit: Now returning dictionaries when querying with wild cards (
None
), and single values otherwise.