Skip to main content

Python dictionary with automatic and arbitrary levels of nestedness

Project description

nested_dict

nested_dict extends defaultdict to support python dict with multiple levels of nested-ness:

Drop in replacement for dict

>>> 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'

Specifying the contained type

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 or str.

dict of lists

#   nested dict of lists
nd = nested_dict(2, list)
nd["mouse"]["2"].append(12)
nd["human"]["1"].append(12)

dict of sets

#   nested dict of sets
nd = nested_dict(2, set)
nd["mouse"]["2"].add("a")
nd["human"]["1"].add("b")

dict of ints

#   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}}

dict of strs

#   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 nested_dict

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. )

Converting to / from dictionaries

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

defaultdict

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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

nested_dict-1.5.4.zip (19.5 kB view hashes)

Uploaded Source

nested_dict-1.5.4.tar.gz (11.8 kB view hashes)

Uploaded Source

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page