Custom Containers

FrozenDict

FrozenDict is unmodifiable dict-like object (like tuple) and therefore can be easy share between object or functions without making copy. State of object (it’s contents) is set in init and then cannot be changed (so called “frozen”). All functions works fine in both Python 2 and 3 thanks to collections.Mapping class, which encapsulate all differences between Python versions (like viewitems in Python 2 renamed to items in Python 3).

It can be created like dict objects (it simply use dict object in __init__) and have same functions like dict, without methods to mutate state like __setitem__. Also unlike dict, the FrozenDict has __hash__ implementation, so that it can be use in hash required places (like dict keys).

class dicttools.FrozenDict(*args, **kwargs)

Object represents pairs key-value, and works like dict, but cannot be modified. Also is hashable in contrast to builtin dict.

__init__(*args, **kwargs)

Init is analogical as dict:

To create empty frozen dictionary:

>>> FrozenDict()
FrozenDict({})

To create frozen dict from mapping:

>>> FrozenDict({'x': 4.5, 'y': 3})
FrozenDict({'x': 4.5, 'y': 3})

To create frozen dict from iterable (of 2-tuple pairs of key and value):

>>> FrozenDict((('x', 4.5), ('y', 3)))
FrozenDict({'x': 4.5, 'y': 3})

Using kwargs:

>>> FrozenDict(x=4.5, y=3)
FrozenDict({'x': 4.5, 'y': 3})

Using kwargs with other method:

>>> FrozenDict({'x': 4.5}, y=3)
FrozenDict({'x': 4.5, 'y': 3})

ChainMap

The ChainMap is similar to collections.ChainMap, but cannot be used as replacement. There are a few important differences. This ChainMap is designed as view for iterable (list, tuple, MappingView, etc.) of maps (dict or other Mapping). ChainMap allow to get, set, or delete items in dicts. When value cannot be founded, KeyException is raised. Given maps is encapsulated inside ChainMap and cannot be called directly. For chaining maps directly keep object separately. Each modification in maps automatically affect the chain, because maps is contained as reference (not as copy).

class dicttools.ChainMap(maps)

Object for multiple dicts aggregation for iterate, getting, setting and deleting as single dict.

When key is many dict then item is consider as the fist founded:

>>> chain = ChainMap([{'a': 1}, {'b': 2}, {'a': 4}])
>>> chain['a']
1

In the same way works deletion and setting:

>>> chain = ChainMap([{'a': 1}, {'b': 2}, {'a': 4}])
>>> chain['a'] = 9
>>> chain
ChainMap([{'a': 9}, {'b': 2}, {'a': 4}])
>>> del chain['a']
>>> chain
ChainMap([{}, {'b': 2}, {'a': 4}])

When key is not in any of dicts (maps) KeyException is raised:

>>> chain = ChainMap([{'a': 1}, {'b': 2}, {'a': 4}])
>>> chain['x'] = 9
Traceback (most recent call last):
...
KeyError: 'x'
__init__(maps)

Create view of iterable of dict tool set. Given argument is handle by reference, hence each change affected this chain. Given maps are encapsulated and cannot be accessed via ChainMap, so keep it separately.

Parameters:maps – iterable of dicts (but not iterator)

TwoWayDict

TwoWayDict is container for storing pairs key-value with additional reversed access. It means, when you assign value to key, the key can be also accessible by value. Is important to handle both keys and variables as hashable.

class dicttools.TwoWayDict(*args, **kwargs)

Object for storing values and keys accessible either by value and by key.

>>> container = TwoWayDict(a=1, b=2)
>>> container[1]
'a'
>>> container['b']
2
>>> container[3] = 'c'
>>> container['c']
3

Both entries of association are automatically updated when one key is changed

>>> container  = TwoWayDict()
>>> container
TwoWayDict({})
>>> container ['c'] = 3
>>> container
TwoWayDict({'c': 3})
>>> container [3]
'c'
>>> container [4] = 'c'
>>> container
TwoWayDict({4: 'c'})
>>> container ['c']
4
>>> container [4]
'c'
__init__(*args, **kwargs)

Init arguments is analogical as dict. Both values and keys have to be hashable (otherwise TypeError is raised). If values is not unique, duplicated elements will be omitted. If there are paris with reversed equivalents only one pair will be contained