Note
- Source code at https://github.com/bunbun/nested-dict
- Documentation at http://nested-dict.readthedocs.org
nested_dict
extends defaultdict
to support python dict
with multiple levels of nested-ness:
>>> from nested_dict import nested_dict >>> nd= nested_dict() >>> nd["one"] = "1" >>> nd[1]["two"] = "1 / 2" >>> nd["uno"][2]["three"] = "1 / 2 / 3" >>> ... for keys_as_tuple, value in nd.items_flat(): ... print ("%-20s == %r" % (keys_as_tuple, value)) ... ('one',) == '1' (1, 'two') == '1 / 2' ('uno', 2, 'three') == '1 / 2 / 3'
- If you want the nested dictionary to hold
- a collection (like the set in the first example) or
- a scalar with useful default values such as
int
orstr
.
# nested dict of lists nd = nested_dict(2, list) nd["mouse"]["2"].append(12) nd["human"]["1"].append(12)
# nested dict of sets nd = nested_dict(2, set) nd["mouse"]["2"].add("a") nd["human"]["1"].add("b")
# nested dict of ints nd = nested_dict(2, int) nd["mouse"]["2"] += 4 nd["human"]["1"] += 5 nd["human"]["1"] += 6 nd.to_dict() #{'human': {'1': 11}, 'mouse': {'2': 4}}
# nested dict of strings nd = nested_dict(2, str) nd["mouse"]["2"] += "a" * 4 nd["human"]["1"] += "b" * 5 nd["human"]["1"] += "c" * 6 nd.to_dict() #{'human': {'1': 'bbbbbcccccc'}, 'mouse': {'2': 'aaaa'}}
Iterating through deep or unevenly nested dictionaries is a bit of a pain without recursion.
nested dict
allows you to flatten the nested levels into tuples before iteration.
You do not need to know beforehand how many levels of nesting you have:
from nested_dict import nested_dict nd= nested_dict() nd["one"] = "1" nd[1]["two"] = "1 / 2" nd["uno"][2]["three"] = "1 / 2 / 3" for keys_as_tuple, value in nd.items_flat(): print ("%-20s == %r" % (keys_as_tuple, value)) # (1, 'two') == '1 / 2' # ('one',) == '1' # ('uno', 2, 'three') == '1 / 2 / 3'
- nested_dict provides
items_flat()
keys_flat()
values_flat()
(iteritems_flat()
, iterkeys_flat()
, and itervalues_flat()
are python 2.7-style synonyms. )
The magic of nested_dict
sometimes gets in the way (of pickleing for example).
- We can convert to and from a vanilla python
dict
using nested_dict.to_dict()
nested_dict constructor
>>> from nested_dict import nested_dict >>> nd= nested_dict() >>> nd["one"] = 1 >>> nd[1]["two"] = "1 / 2" # # convert nested_dict -> dict and pickle # >>> nd.to_dict() {1: {'two': '1 / 2'}, 'one': 1} >>> import pickle >>> binary_representation = pickle.dumps(nd.to_dict()) # # convert dict -> nested_dict # >>> normal_dict = pickle.loads(binary_representation) >>> new_nd = nested_dict(normal_dict) >>> nd == new_nd True
nested_dict
extends collections.defaultdict
You can get arbitrarily-nested "auto-vivifying" dictionaries using defaultdict.
from collections import defaultdict nested_dict = lambda: defaultdict(nested_dict) nd = nested_dict() nd[1][2]["three"][4] = 5 nd["one"]["two"]["three"][4] = 5
However, only nested_dict
supports a dict
of dict
of sets
etc.