DeepDict#

class sigmaepsilon.deepdict.deepdict.DeepDict(*args, **kwargs)#

An nested dictionary class with a self-replicating default factory. It can be a drop-in replacement for the bulit-in dictionary type, but it’s more capable as it handles nested layouts.

Parameters:
  • *args* (tuple, Optional) – Extra positional arguments are forwarded to the dict class.

  • **kwargs** (dictionary, Optional) – Extra keyword arguments are forwarded to the dict class.

Examples

Basic usage:

>>> from sigmaepsilon.deepdict import DeepDict
>>> d = {'a' : {'aa' : {'aaa' : 0}}, 'b' : 1, 'c' : {'cc' : 2}}
>>> dd = DeepDict(d)
>>> list(dd.values(deep=True))
[0, 1, 2]
property address: Tuple | None#

Returns the address of an item or None it has no parent.

containers(*, inclusive: bool | None = False, deep: bool | None = True, dtype: Any | None = None) Iterable[T]#

Returns all the containers in a nested layout. A dictionary in a nested layout is called a container, only if it contains other containers (it is a parent).

Parameters:
  • inclusive (bool, Optional) – If True, the object the call is made upon also gets returned. This can be important if you make the call on the root object, which most of the time does not hold onto relevant data directly. Default is False.

  • deep (bool, Optional) – If True the parser goes into nested dictionaries. Default is True

  • dtype (Any, Optional) – Constrains the type of the returned objects. Default is None, which means no restriction.

Returns:

Returns a generator object.

Return type:

generator

Examples

A simple example:

>>> from sigmaepsilon.deepdict import DeepDict
>>> data = DeepDict()
>>> data['a', 'b', 'c'] = 1
>>> [c.key for c in data.containers()]
['a', 'b']

We can see, that dictionaries ‘a’ and ‘b’ are returned as containers, but ‘c’ isn’t, because it is not a parent, there are no deeper levels.

>>> [c.key for c in data.containers(inclusive=True, deep=True)]
[None, 'a', 'b']
>>> [c.key for c in data.containers(inclusive=True, deep=False)]
[None, 'a']
>>> [c.key for c in data.containers(inclusive=False, deep=True)]
['a', 'b']
>>> [c.key for c in data.containers(inclusive=False, deep=False)]
['a']
property depth: int#

Retuns the depth of the actual instance in a layout, starting from 0..

is_leaf(dtype: Any | None = None) bool#

Returns True, if the instance has no children.

Parameters:

dtype (Any, Optional) – It can be a type that controls what is considered as a children. It is None by default, which means that only instances of the same class are considered children. In this case, a simple dict wouldn’t make it.

Example

>>> from sigmaepsilon.deepdict import DeepDict
>>> d = {
...     "a" : {"aa" : 1},
...     "b" : 2,
...     "c" : {"cc" : {"ccc" : 3}},
... }
>>> dd = DeepDict.wrap(d)
>>> dd.is_leaf(), dd["a"].is_leaf()
(False, True)
is_root() bool#

Returns True, if the instance is the root.

items(*, deep: bool | None = False, return_address: bool | None = False) Iterable[Tuple]#

Returns the items. When called without arguments, it works the same as for standard dictionaries.

Parameters:
  • deep (bool, Optional) – If True the parser goes into nested dictionaries. Default is True.

  • return_address (bool, Optional) – If True, addresses are returned instead of keys. The difference is similar than that of absolute and repative paths. In this respect, keys are the relative paths (relative to the parent), and addresses are absolute paths (relative to the root). Default is False.

property key: Hashable | None#

Returns the key of the instance, or None if it has no parent.

keys(*, deep: bool | None = False, return_address: bool | None = False) Iterable[Hashable]#

Returns the keys. When called without arguments, it works the same as for standard dictionaries.

Parameters:
  • deep (bool, Optional) – If True the parser goes into nested dictionaries. Default is True.

  • return_address (bool, Optional) – If True, addresses are returned instead of keys. The difference is similar than that of absolute and repative paths. In this respect, keys are the relative paths (relative to the parent), and addresses are absolute paths (relative to the root). Default is False.

lock() None#

Locks the layout of the dictionary. If a DeepDict is locked, missing keys are handled the same way as they would’ve been handled if it was a ´dict´. Also, setting or deleting items in a locked dictionary and not possible and you will experience an error upon trying.

property locked: bool#

Returns True if the object is locked. The property is equpped with a setter.

property name: str | None#

The name of the dictionary. It is used for representation purposes. If a name is not specified, the key is returned here. Setting a name may be important for the top level entity, since it has no key.

property parent: T | None | DeepDict#

Returns the parent of the instance, or None if it has no parent.

property root: T | None | DeepDict#

Returns the top-level object in a nested layout.

unlock() None#

Releases the layout of the dictionary. If a DeepDict is not locked, a missing key creates a new level in the layout, also setting and deleting items becomes an option.

values(*, deep: bool | None = False, return_address: bool | None = False) Iterable[Any | T]#

Returns the values. When called without arguments, it works the same as for standard dictionaries.

Parameters:
  • deep (bool, Optional) – If True the parser goes into nested dictionaries. Default is True.

  • return_address (bool, Optional) – If True, addresses are returned as well. Default is False.

classmethod wrap(d: dict, copy: bool = False, deepcopy: bool = False) T | DeepDict#

Wraps a dictionary with all nested dictionaries and content.

Parameters:
  • d (dict) – The dictionary to wrap.

  • copy (bool, Optional) – If True, shallow copies of the values are stored. Default is False.

  • deepcopy (bool, Optional) – If True, deep copies of the values are stored. Default is False.

Example

>>> from sigmaepsilon.deepdict import DeepDict
>>> d = {
...     "a" : {"aa" : 1},
...     "b" : 2,
...     "c" : {"cc" : {"ccc" : 3}},
... }
>>> DeepDict.wrap(d)["c", "cc", "ccc"]
3
>>> list(DeepDict.wrap(d).items(deep=True))
[('aa', 1), ('b', 2), ('ccc', 3)]
class sigmaepsilon.deepdict.deepdict.Key(arg: Any)#

Helper class for keys.

class sigmaepsilon.deepdict.deepdict.Value(arg: Any)#

Helper class for values.