Name | flatten-dict JSON |
Version |
0.4.2
JSON |
| download |
home_page | https://github.com/ianlini/flatten-dict |
Summary | A flexible utility for flattening and unflattening dict-like objects in Python. |
upload_time | 2021-08-08 09:56:51 |
maintainer | |
docs_url | None |
author | Ian Lin |
requires_python | >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.* |
license | MIT |
keywords |
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
flatten-dict
============
.. image:: https://github.com/ianlini/flatten-dict/actions/workflows/main.yml/badge.svg
:target: https://github.com/ianlini/flatten-dict/actions
.. image:: https://img.shields.io/pypi/v/flatten-dict.svg
:target: https://pypi.org/project/flatten-dict/
.. image:: https://img.shields.io/pypi/l/flatten-dict.svg
:target: https://github.com/ianlini/flatten-dict/blob/master/LICENSE
.. image:: https://img.shields.io/github/stars/ianlini/flatten-dict.svg?style=social
:target: https://github.com/ianlini/flatten-dict
A flexible utility for flattening and unflattening dict-like objects in Python.
Introduction
------------
This package provides a function ``flatten()`` for flattening dict-like objects in Python 2.7 and 3.5~3.8.
It also provides some key joining methods (reducer), and you can choose the reducer you want or even implement your own reducer.
You can also invert the resulting flat dict using ``unflatten()``.
Installation
------------
.. code-block:: bash
pip install flatten-dict
Documentation
-------------
Flatten
```````
.. code-block:: python
def flatten(d, reducer='tuple', inverse=False, enumerate_types=(), keep_empty_types=()):
"""Flatten `Mapping` object.
Parameters
----------
d : dict-like object
The dict that will be flattened.
reducer : {'tuple', 'path', 'underscore', 'dot', Callable}
The key joining method. If a `Callable` is given, the `Callable` will be
used to reduce.
'tuple': The resulting key will be tuple of the original keys.
'path': Use `os.path.join` to join keys.
'underscore': Use underscores to join keys.
'dot': Use dots to join keys.
inverse : bool
Whether you want invert the resulting key and value.
max_flatten_depth : int
Maximum depth to merge.
enumerate_types : Sequence[type]
Flatten these types using `enumerate`.
For example, if we set `enumerate_types` to ``(list,)``,
`list` indices become keys: ``{'a': ['b', 'c']}`` -> ``{('a', 0): 'b', ('a', 1): 'c'}``.
keep_empty_types : Sequence[type]
By default, ``flatten({1: 2, 3: {}})`` will give you ``{(1,): 2}``, that is, the key ``3``
will disappear.
This is also applied for the types in `enumerate_types`, that is,
``flatten({1: 2, 3: []}, enumerate_types=(list,))`` will give you ``{(1,): 2}``.
If you want to keep those empty values, you can specify the types in `keep_empty_types`:
>>> flatten({1: 2, 3: {}}, keep_empty_types=(dict,))
{(1,): 2, (3,): {}}
Returns
-------
flat_dict : dict
"""
Examples
::::::::
>>> from flatten_dict import flatten
>>> from pprint import pprint
>>> normal_dict = {
... 'a': '0',
... 'b': {
... 'a': '1.0',
... 'b': '1.1',
... },
... 'c': {
... 'a': '2.0',
... 'b': {
... 'a': '2.1.0',
... 'b': '2.1.1',
... },
... },
... }
>>> pprint(flatten(normal_dict))
{('a',): '0',
('b', 'a'): '1.0',
('b', 'b'): '1.1',
('c', 'a'): '2.0',
('c', 'b', 'a'): '2.1.0',
('c', 'b', 'b'): '2.1.1'}
>>> pprint(flatten(normal_dict, reducer='path'))
{'a': '0',
'b/a': '1.0',
'b/b': '1.1',
'c/a': '2.0',
'c/b/a': '2.1.0',
'c/b/b': '2.1.1'}
>>> pprint(flatten(normal_dict, reducer='path', inverse=True))
{'0': 'a',
'1.0': 'b/a',
'1.1': 'b/b',
'2.0': 'c/a',
'2.1.0': 'c/b/a',
'2.1.1': 'c/b/b'}
>>> pprint(flatten(normal_dict, reducer='path', max_flatten_depth=2))
{'a': '0',
'b/a': '1.0',
'b/b': '1.1',
'c/a': '2.0',
'c/b': {'a': '2.1.0', 'b': '2.1.1'}}
The `reducer` parameter supports ``'tuple'``, ``'path'``, ``'underscore'``, ``'dot'`` and `Callable`. We can customize the reducer using a function:
>>> def underscore_reducer(k1, k2):
... if k1 is None:
... return k2
... else:
... return k1 + "_" + k2
...
>>> pprint(flatten(normal_dict, reducer=underscore_reducer))
{'a': '0',
'b_a': '1.0',
'b_b': '1.1',
'c_a': '2.0',
'c_b_a': '2.1.0',
'c_b_b': '2.1.1'}
There is also a factory function `make_reducer()` to help you create customized reducer. The function currently only supports customized delimiter:
>>> from flatten_dict.reducers import make_reducer
>>> pprint(flatten(normal_dict, reducer=make_reducer(delimiter='_')))
{'a': '0',
'b_a': '1.0',
'b_b': '1.1',
'c_a': '2.0',
'c_b_a': '2.1.0',
'c_b_b': '2.1.1'}
If we have some iterable (e.g., `list`) in the `dict`, we will normally get this:
>>> flatten({'a': [1, 2, 3], 'b': 'c'})
{('a',): [1, 2, 3], ('b',): 'c'}
If we want to use its indices as keys, then we can use the parameter `enumerate_types`:
>>> flatten({'a': [1, 2, 3], 'b': 'c'}, enumerate_types=(list,))
{('a', 0): 1, ('a', 1): 2, ('a', 2): 3, ('b',): 'c'}
We can even flatten a `list` directly:
>>> flatten([1, 2, 3], enumerate_types=(list,))
{(0,): 1, (1,): 2, (2,): 3}
If there is an empty dict in the values, by default, it will disappear after flattened:
>>> flatten({1: 2, 3: {}})
{(1,): 2}
We can keep the empty dict in the result using ``keep_empty_types=(dict,)``:
>>> flatten({1: 2, 3: {}}, keep_empty_types=(dict,))
{(1,): 2, (3,): {}}
Unflatten
`````````
.. code-block:: python
def unflatten(d, splitter='tuple', inverse=False):
"""Unflatten dict-like object.
Parameters
----------
d : dict-like object
The dict that will be unflattened.
splitter : {'tuple', 'path', 'underscore', 'dot', Callable}
The key splitting method. If a Callable is given, the Callable will be
used to split `d`.
'tuple': Use each element in the tuple key as the key of the unflattened dict.
'path': Use `pathlib.Path.parts` to split keys.
'underscore': Use underscores to split keys.
'dot': Use underscores to split keys.
inverse : bool
Whether you want to invert the key and value before flattening.
Returns
-------
unflattened_dict : dict
"""
Examples
::::::::
>>> from pprint import pprint
>>> from flatten_dict import unflatten
>>> flat_dict = {
... ('a',): '0',
... ('b', 'a'): '1.0',
... ('b', 'b'): '1.1',
... ('c', 'a'): '2.0',
... ('c', 'b', 'a'): '2.1.0',
... ('c', 'b', 'b'): '2.1.1',
... }
>>> pprint(unflatten(flat_dict))
{'a': '0',
'b': {'a': '1.0', 'b': '1.1'},
'c': {'a': '2.0', 'b': {'a': '2.1.0', 'b': '2.1.1'}}}
>>> flat_dict = {
... 'a': '0',
... 'b/a': '1.0',
... 'b/b': '1.1',
... 'c/a': '2.0',
... 'c/b/a': '2.1.0',
... 'c/b/b': '2.1.1',
... }
>>> pprint(unflatten(flat_dict, splitter='path'))
{'a': '0',
'b': {'a': '1.0', 'b': '1.1'},
'c': {'a': '2.0', 'b': {'a': '2.1.0', 'b': '2.1.1'}}}
>>> flat_dict = {
... '0': 'a',
... '1.0': 'b/a',
... '1.1': 'b/b',
... '2.0': 'c/a',
... '2.1.0': 'c/b/a',
... '2.1.1': 'c/b/b',
... }
>>> pprint(unflatten(flat_dict, splitter='path', inverse=True))
{'a': '0',
'b': {'a': '1.0', 'b': '1.1'},
'c': {'a': '2.0', 'b': {'a': '2.1.0', 'b': '2.1.1'}}}
The `splitter` parameter supports ``'tuple'``, ``'path'``, ``'underscore'``, ``'dot'`` and `Callable`. We can customize the reducer using a function:
>>> def underscore_splitter(flat_key):
... return flat_key.split("_")
...
>>> flat_dict = {
... 'a': '0',
... 'b_a': '1.0',
... 'b_b': '1.1',
... 'c_a': '2.0',
... 'c_b_a': '2.1.0',
... 'c_b_b': '2.1.1',
... }
>>> pprint(unflatten(flat_dict, splitter=underscore_splitter))
{'a': '0',
'b': {'a': '1.0', 'b': '1.1'},
'c': {'a': '2.0', 'b': {'a': '2.1.0', 'b': '2.1.1'}}}
There is also a factory function `make_splitter()` to help you create customized splitter. The function currently only supports customized delimiter:
>>> from flatten_dict.splitters import make_splitter
>>> pprint(unflatten(flat_dict, splitter=make_splitter(delimiter='_')))
{'a': '0',
'b': {'a': '1.0', 'b': '1.1'},
'c': {'a': '2.0', 'b': {'a': '2.1.0', 'b': '2.1.1'}}}
Raw data
{
"_id": null,
"home_page": "https://github.com/ianlini/flatten-dict",
"name": "flatten-dict",
"maintainer": "",
"docs_url": null,
"requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*",
"maintainer_email": "",
"keywords": "",
"author": "Ian Lin",
"author_email": "you@example.com",
"download_url": "https://files.pythonhosted.org/packages/89/c6/5fe21639369f2ea609c964e20870b5c6c98a134ef12af848a7776ddbabe3/flatten-dict-0.4.2.tar.gz",
"platform": "",
"description": "flatten-dict\n============\n.. image:: https://github.com/ianlini/flatten-dict/actions/workflows/main.yml/badge.svg\n :target: https://github.com/ianlini/flatten-dict/actions\n.. image:: https://img.shields.io/pypi/v/flatten-dict.svg\n :target: https://pypi.org/project/flatten-dict/\n.. image:: https://img.shields.io/pypi/l/flatten-dict.svg\n :target: https://github.com/ianlini/flatten-dict/blob/master/LICENSE\n.. image:: https://img.shields.io/github/stars/ianlini/flatten-dict.svg?style=social\n :target: https://github.com/ianlini/flatten-dict\n\nA flexible utility for flattening and unflattening dict-like objects in Python.\n\n\nIntroduction\n------------\nThis package provides a function ``flatten()`` for flattening dict-like objects in Python 2.7 and 3.5~3.8.\nIt also provides some key joining methods (reducer), and you can choose the reducer you want or even implement your own reducer.\nYou can also invert the resulting flat dict using ``unflatten()``.\n\nInstallation\n------------\n\n.. code-block:: bash\n\n pip install flatten-dict\n\nDocumentation\n-------------\n\nFlatten\n```````\n\n.. code-block:: python\n\n def flatten(d, reducer='tuple', inverse=False, enumerate_types=(), keep_empty_types=()):\n \"\"\"Flatten `Mapping` object.\n\n Parameters\n ----------\n d : dict-like object\n The dict that will be flattened.\n reducer : {'tuple', 'path', 'underscore', 'dot', Callable}\n The key joining method. If a `Callable` is given, the `Callable` will be\n used to reduce.\n 'tuple': The resulting key will be tuple of the original keys.\n 'path': Use `os.path.join` to join keys.\n 'underscore': Use underscores to join keys.\n 'dot': Use dots to join keys.\n inverse : bool\n Whether you want invert the resulting key and value.\n max_flatten_depth : int\n Maximum depth to merge.\n enumerate_types : Sequence[type]\n Flatten these types using `enumerate`.\n For example, if we set `enumerate_types` to ``(list,)``,\n `list` indices become keys: ``{'a': ['b', 'c']}`` -> ``{('a', 0): 'b', ('a', 1): 'c'}``.\n keep_empty_types : Sequence[type]\n By default, ``flatten({1: 2, 3: {}})`` will give you ``{(1,): 2}``, that is, the key ``3``\n will disappear.\n This is also applied for the types in `enumerate_types`, that is,\n ``flatten({1: 2, 3: []}, enumerate_types=(list,))`` will give you ``{(1,): 2}``.\n If you want to keep those empty values, you can specify the types in `keep_empty_types`:\n\n >>> flatten({1: 2, 3: {}}, keep_empty_types=(dict,))\n {(1,): 2, (3,): {}}\n\n Returns\n -------\n flat_dict : dict\n \"\"\"\n\nExamples\n::::::::\n\n>>> from flatten_dict import flatten\n>>> from pprint import pprint\n>>> normal_dict = {\n... 'a': '0',\n... 'b': {\n... 'a': '1.0',\n... 'b': '1.1',\n... },\n... 'c': {\n... 'a': '2.0',\n... 'b': {\n... 'a': '2.1.0',\n... 'b': '2.1.1',\n... },\n... },\n... }\n>>> pprint(flatten(normal_dict))\n{('a',): '0',\n ('b', 'a'): '1.0',\n ('b', 'b'): '1.1',\n ('c', 'a'): '2.0',\n ('c', 'b', 'a'): '2.1.0',\n ('c', 'b', 'b'): '2.1.1'}\n>>> pprint(flatten(normal_dict, reducer='path'))\n{'a': '0',\n 'b/a': '1.0',\n 'b/b': '1.1',\n 'c/a': '2.0',\n 'c/b/a': '2.1.0',\n 'c/b/b': '2.1.1'}\n>>> pprint(flatten(normal_dict, reducer='path', inverse=True))\n{'0': 'a',\n '1.0': 'b/a',\n '1.1': 'b/b',\n '2.0': 'c/a',\n '2.1.0': 'c/b/a',\n '2.1.1': 'c/b/b'}\n>>> pprint(flatten(normal_dict, reducer='path', max_flatten_depth=2))\n{'a': '0',\n 'b/a': '1.0',\n 'b/b': '1.1',\n 'c/a': '2.0',\n 'c/b': {'a': '2.1.0', 'b': '2.1.1'}}\n\nThe `reducer` parameter supports ``'tuple'``, ``'path'``, ``'underscore'``, ``'dot'`` and `Callable`. We can customize the reducer using a function:\n\n>>> def underscore_reducer(k1, k2):\n... if k1 is None:\n... return k2\n... else:\n... return k1 + \"_\" + k2\n...\n>>> pprint(flatten(normal_dict, reducer=underscore_reducer))\n{'a': '0',\n 'b_a': '1.0',\n 'b_b': '1.1',\n 'c_a': '2.0',\n 'c_b_a': '2.1.0',\n 'c_b_b': '2.1.1'}\n\nThere is also a factory function `make_reducer()` to help you create customized reducer. The function currently only supports customized delimiter:\n\n>>> from flatten_dict.reducers import make_reducer\n>>> pprint(flatten(normal_dict, reducer=make_reducer(delimiter='_')))\n{'a': '0',\n 'b_a': '1.0',\n 'b_b': '1.1',\n 'c_a': '2.0',\n 'c_b_a': '2.1.0',\n 'c_b_b': '2.1.1'}\n\nIf we have some iterable (e.g., `list`) in the `dict`, we will normally get this:\n\n>>> flatten({'a': [1, 2, 3], 'b': 'c'})\n{('a',): [1, 2, 3], ('b',): 'c'}\n\nIf we want to use its indices as keys, then we can use the parameter `enumerate_types`:\n\n>>> flatten({'a': [1, 2, 3], 'b': 'c'}, enumerate_types=(list,))\n{('a', 0): 1, ('a', 1): 2, ('a', 2): 3, ('b',): 'c'}\n\nWe can even flatten a `list` directly:\n\n>>> flatten([1, 2, 3], enumerate_types=(list,))\n{(0,): 1, (1,): 2, (2,): 3}\n\nIf there is an empty dict in the values, by default, it will disappear after flattened:\n\n>>> flatten({1: 2, 3: {}})\n{(1,): 2}\n\nWe can keep the empty dict in the result using ``keep_empty_types=(dict,)``:\n\n>>> flatten({1: 2, 3: {}}, keep_empty_types=(dict,))\n{(1,): 2, (3,): {}}\n\nUnflatten\n`````````\n\n.. code-block:: python\n\n def unflatten(d, splitter='tuple', inverse=False):\n \"\"\"Unflatten dict-like object.\n\n Parameters\n ----------\n d : dict-like object\n The dict that will be unflattened.\n splitter : {'tuple', 'path', 'underscore', 'dot', Callable}\n The key splitting method. If a Callable is given, the Callable will be\n used to split `d`.\n 'tuple': Use each element in the tuple key as the key of the unflattened dict.\n 'path': Use `pathlib.Path.parts` to split keys.\n 'underscore': Use underscores to split keys.\n 'dot': Use underscores to split keys.\n inverse : bool\n Whether you want to invert the key and value before flattening.\n\n Returns\n -------\n unflattened_dict : dict\n \"\"\"\n\nExamples\n::::::::\n\n>>> from pprint import pprint\n>>> from flatten_dict import unflatten\n>>> flat_dict = {\n... ('a',): '0',\n... ('b', 'a'): '1.0',\n... ('b', 'b'): '1.1',\n... ('c', 'a'): '2.0',\n... ('c', 'b', 'a'): '2.1.0',\n... ('c', 'b', 'b'): '2.1.1',\n... }\n>>> pprint(unflatten(flat_dict))\n{'a': '0',\n 'b': {'a': '1.0', 'b': '1.1'},\n 'c': {'a': '2.0', 'b': {'a': '2.1.0', 'b': '2.1.1'}}}\n>>> flat_dict = {\n... 'a': '0',\n... 'b/a': '1.0',\n... 'b/b': '1.1',\n... 'c/a': '2.0',\n... 'c/b/a': '2.1.0',\n... 'c/b/b': '2.1.1',\n... }\n>>> pprint(unflatten(flat_dict, splitter='path'))\n{'a': '0',\n 'b': {'a': '1.0', 'b': '1.1'},\n 'c': {'a': '2.0', 'b': {'a': '2.1.0', 'b': '2.1.1'}}}\n>>> flat_dict = {\n... '0': 'a',\n... '1.0': 'b/a',\n... '1.1': 'b/b',\n... '2.0': 'c/a',\n... '2.1.0': 'c/b/a',\n... '2.1.1': 'c/b/b',\n... }\n>>> pprint(unflatten(flat_dict, splitter='path', inverse=True))\n{'a': '0',\n 'b': {'a': '1.0', 'b': '1.1'},\n 'c': {'a': '2.0', 'b': {'a': '2.1.0', 'b': '2.1.1'}}}\n\nThe `splitter` parameter supports ``'tuple'``, ``'path'``, ``'underscore'``, ``'dot'`` and `Callable`. We can customize the reducer using a function:\n\n>>> def underscore_splitter(flat_key):\n... return flat_key.split(\"_\")\n...\n>>> flat_dict = {\n... 'a': '0',\n... 'b_a': '1.0',\n... 'b_b': '1.1',\n... 'c_a': '2.0',\n... 'c_b_a': '2.1.0',\n... 'c_b_b': '2.1.1',\n... }\n>>> pprint(unflatten(flat_dict, splitter=underscore_splitter))\n{'a': '0',\n 'b': {'a': '1.0', 'b': '1.1'},\n 'c': {'a': '2.0', 'b': {'a': '2.1.0', 'b': '2.1.1'}}}\n\nThere is also a factory function `make_splitter()` to help you create customized splitter. The function currently only supports customized delimiter:\n\n>>> from flatten_dict.splitters import make_splitter\n>>> pprint(unflatten(flat_dict, splitter=make_splitter(delimiter='_')))\n{'a': '0',\n 'b': {'a': '1.0', 'b': '1.1'},\n 'c': {'a': '2.0', 'b': {'a': '2.1.0', 'b': '2.1.1'}}}\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A flexible utility for flattening and unflattening dict-like objects in Python.",
"version": "0.4.2",
"project_urls": {
"Homepage": "https://github.com/ianlini/flatten-dict",
"Repository": "https://github.com/ianlini/flatten-dict"
},
"split_keywords": [],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "43f5ee39c6e92acc742c052f137b47c210cd0a1b72dcd3f98495528bb4d27761",
"md5": "6419e84c5cb5d5dca732eae85e3ece4f",
"sha256": "7e245b20c4c718981212210eec4284a330c9f713e632e98765560e05421e48ad"
},
"downloads": -1,
"filename": "flatten_dict-0.4.2-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "6419e84c5cb5d5dca732eae85e3ece4f",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*",
"size": 9656,
"upload_time": "2021-08-08T09:56:54",
"upload_time_iso_8601": "2021-08-08T09:56:54.313653Z",
"url": "https://files.pythonhosted.org/packages/43/f5/ee39c6e92acc742c052f137b47c210cd0a1b72dcd3f98495528bb4d27761/flatten_dict-0.4.2-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "89c65fe21639369f2ea609c964e20870b5c6c98a134ef12af848a7776ddbabe3",
"md5": "897952161d3ef40807de444610521f01",
"sha256": "506a96b6e6f805b81ae46a0f9f31290beb5fa79ded9d80dbe1b7fa236ab43076"
},
"downloads": -1,
"filename": "flatten-dict-0.4.2.tar.gz",
"has_sig": false,
"md5_digest": "897952161d3ef40807de444610521f01",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*",
"size": 10362,
"upload_time": "2021-08-08T09:56:51",
"upload_time_iso_8601": "2021-08-08T09:56:51.455294Z",
"url": "https://files.pythonhosted.org/packages/89/c6/5fe21639369f2ea609c964e20870b5c6c98a134ef12af848a7776ddbabe3/flatten-dict-0.4.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2021-08-08 09:56:51",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "ianlini",
"github_project": "flatten-dict",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"tox": true,
"lcname": "flatten-dict"
}