Benchmarking for dot-accessible dict packages in python
More test ideas? Submit an issue!
As of 2022-09-21 23:11:19.354375
| Package | Version | Last Commit | Stars | Forks | Description |
|---|---|---|---|---|---|
| addict | 2.4.0 | Tue, 05 Jan 2021 07:16:38 GMT | 2277 | 137 | (i) |
| python-box | 6.0.2 | Sat, 02 Apr 2022 02:24:21 GMT | 2062 | 89 | (i) |
| dotmap | 1.3.30 | Wed, 06 Apr 2022 16:26:33 GMT | 366 | 43 | (i) |
| dotwiz | 0.4.0 | Wed, 21 Sep 2022 22:23:19 GMT | 20 | 1 | (i) |
| easydict | 1.9 | Sun, 28 Feb 2021 10:26:53 GMT | 207 | 39 | (i) |
| dotsi | 0.0.3 | Sun, 22 Nov 2020 16:48:22 GMT | 18 | 1 | (i) |
| dictlib | 1.1.5 | Thu, 15 Aug 2019 23:10:47 GMT | 14 | 3 | (i) |
| diot | 0.1.6 | Thu, 12 May 2022 20:37:59 GMT | 7 | 2 | (i) |
How the packages create an object of the dict subclass
| Created | |
|---|---|
| addict | {'a': {'b': {'c': 1}}} Type: Dict |
| python-box | {'a': {'b': {'c': 1}}} Type: Box |
| dotmap | DotMap(a=DotMap(b=DotMap(c=1))) Type: DotMap |
| dotwiz | ✫(a=✫(b=✫(c=1))) Type: DotWiz |
| easydict | {'a': {'b': {'c': 1}}} Type: EasyDict |
| dotsi | {'a': {'b': {'c': 1}}} Type: DotsiDict |
| dictlib | {'a': {'b': {'c': 1}}} Type: Dict |
| diot | {'a': Diot({'b': Diot({'c': 1})})} Type: Diot |
How the packages create a dict with preserved keys
(e.g. keys, values, items, etc)
Literally, {"keys": 1}
| Created or error | |
|---|---|
| addict | {'keys': 1} |
| python-box | {'keys': 1} |
| dotmap | DotMap(keys=1) |
| dotwiz | ✫(keys=1) |
| easydict | {'keys': 1} |
| dotsi | {'keys': 1} |
| dictlib | Key 'keys' conflicts with reserved word |
| diot | {'keys': 1} |
How the packages create a dict with magic keys
(e.g. __name__, __class__, etc)
Literally, {"__name__": 1}
| Created or error | |
|---|---|
| addict | {'__name__': 1} |
| python-box | {'__name__': 1} |
| dotmap | DotMap(__name__=1) |
| dotwiz | ✫(__name__=1) |
| easydict | {'__name__': 1} |
| dotsi | {'__name__': 1} |
| dictlib | {'__name__': 1} |
| diot | {'__name__': 1} |
How the packages to access values
Literally 1 from {"a": {"b": {"c": 1}}}
| Way to access value | |
|---|---|
| addict | <dict>.a.b.c or <dict>['a']['b']['c'] |
| python-box | <dict>.a.b.c or <dict>['a']['b']['c'] |
| dotmap | <dict>.a.b.c or <dict>['a']['b']['c'] |
| dotwiz | <dict>.a.b.c or <dict>['a']['b']['c'] |
| easydict | <dict>.a.b.c or <dict>['a']['b']['c'] |
| dotsi | <dict>.a.b.c or <dict>['a']['b']['c'] |
| dictlib | dictlib.dig(<dict>, 'a.b.c') or dictlib.Dict(<dict>).a.b.c |
| diot | <dict>.a.b.c or <dict>['a']['b']['c'] |
Whether recursive dot access is supported when there are lists in the dict
Literally <dict>.a.b[0].c from {"a": {"b": [{"c": 1}, {"d": 2}]}}
| Value or error | |
|---|---|
| addict | 1 |
| python-box | 1 |
| dotmap | 1 |
| dotwiz | 1 |
| easydict | 1 |
| dotsi | 1 |
| dictlib | AttributeError: 'dict' object has no attribute 'c' |
| diot | 1 |
Whether a hierarchical structure is created by dot notation
Literally <dict>.a.b.c = 1 creates {"a": {"b": {"c": 1}}}
| Created or error | |
|---|---|
| addict | {'a': {'b': {'c': 1}}} |
| python-box | KeyError: "'Box' object has no attribute 'a'" |
| dotmap | DotMap(a=DotMap(b=DotMap(c=1))) |
| dotwiz | AttributeError: 'DotWiz' object has no attribute 'a' |
| easydict | AttributeError: 'EasyDict' object has no attribute 'a' |
| dotsi | KeyError: 'a' |
| dictlib | KeyError: 'a' |
| diot | AttributeError: a |
How to access values with conflict keys
Literally, accessing values from {"keys": 1, "__name__": 2}
| Package | obj.keys |
obj['keys'] |
obj.__name__ |
obj['__name__'] |
|---|---|---|---|---|
| addict | <built-in method keys of Dict object at 0x7f4455a49c70> |
1 |
2 |
2 |
| python-box | <bound method Box.keys of Box({'keys': 1, '__name__': 2})> |
1 |
2 |
2 |
| dotmap | <bound method DotMap.keys of DotMap(keys=1, __name__=2)> |
1 |
AttributeError: __name__ |
2 |
| dotwiz | 1 |
1 |
2 |
2 |
| easydict | 1 |
1 |
2 |
2 |
| dotsi | <built-in method keys of DotsiDict object at 0x7f4455a49c70> |
1 |
2 |
2 |
| dictlib | Can't create |
Can't create |
Can't create |
Can't create |
| diot | <built-in method keys of Diot object at 0x7f4455a49c70> |
1 |
2 |
2 |
How the values with keys with dash are accessed
Literally <dict>.a_b for {"a-b": 1}
| Package | obj.a_b |
obj['a_b'] |
obj['a-b'] |
|---|---|---|---|
| addict | {} |
{} |
1 |
| python-box | 1 |
KeyError: "'a_b'" |
1 |
| dotmap | DotMap() |
DotMap() |
1 |
| dotwiz | AttributeError: 'DotWiz' object has no attribute 'a_b' |
KeyError: 'a_b' |
1 |
| easydict | AttributeError: 'EasyDict' object has no attribute 'a_b' |
KeyError: 'a_b' |
1 |
| dotsi | KeyError: 'a_b' |
KeyError: 'a_b' |
1 |
| dictlib | 1 |
1 |
1 |
| diot | 1 |
1 |
1 |
Whether the packages support frozen dicts
| Support? and how? | |
|---|---|
| addict | <dict>.freeze()/.unfreeze() |
| python-box | Box(<dict>, frozen_box=True) |
| dotmap | Not supported |
| dotwiz | Not supported |
| easydict | Not supported |
| dotsi | Not supported |
| dictlib | Not supported |
| diot | FrozenDiot(<dict>) or Diot(<dict>, diot_frozen=True) |
Whether the packages support key transformation for dot access
For example: making <dict>.a_b to access value from {"a.b": 1}
| Support? and how? | |
|---|---|
| addict | Not supported |
| python-box | Using Conversion Box or Camel Killer Box |
| dotmap | Not supported |
| dotwiz | DotWizPlus turns special-cased keys, such as names with spaces, into valid snake_case words |
| easydict | Not supported |
| dotsi | Not supported |
| dictlib | Not supported |
| diot | Support custom transform function: Diot(..., diot_transform =...) |