Flatten-dict
Flatten-dict is a flexible utility library for flattening and unflattening dict-like objects in Python. It supports custom key formatters (splitters/reducers) and handles nested structures, lists, and tuples. The current version is 0.4.2, and it maintains an active release cadence with improvements and bug fixes.
Common errors
-
ModuleNotFoundError: No module named 'flatten_dict'
cause The `flatten-dict` library is installed using `pip install flatten-dict`, but the Python module to import is `flatten_dict`. This error occurs if the package is not installed or if there's a typo in the import statement.fixFirst, ensure the library is installed: `pip install flatten-dict`. Then, import it correctly: `from flatten_dict import flatten, unflatten`. -
AttributeError: 'bool' object has no attribute 'items'
cause This error typically occurs when the `flatten` function encounters a non-dictionary object (like a boolean, string, or integer) in a nested structure where it expects another dictionary to iterate over using `.items()`. This can happen if your input dictionary contains unexpected data types or if the default flattening logic is applied to structures not intended to be fully flattened as dictionaries.fixEnsure that nested structures are dict-like where `flatten` expects them. If your dictionary contains lists, tuples, or other iterables that you want to flatten, use the `enumerate_types` parameter (e.g., `flatten(my_dict, enumerate_types=(list,))`) to tell `flatten-dict` how to handle them. For other non-dict types, ensure they are at the 'leaf' level or handle them with custom reducers if complex flattening is required. -
unflatten makes dicts instead of lists when index is list index
cause When flattening a dictionary containing lists, `flatten-dict` by default might not store the list indices in a way that `unflatten` can correctly reconstruct them as lists. Instead, `unflatten` might recreate them as dictionaries with integer keys.fixTo ensure `unflatten` correctly reconstructs lists, you must explicitly tell `flatten` to enumerate list (and/or tuple) types during the flattening process using the `enumerate_types` parameter. For example: `flat_dict = flatten(original_dict, enumerate_types=(list,))`. Then, `unflatten(flat_dict)` will restore lists correctly.
Warnings
- breaking The modules `flatten_dict.splitter` and `flatten_dict.reducer` were deprecated in version 0.4.0 in favor of their pluralized counterparts, `flatten_dict.splitters` and `flatten_dict.reducers`. Direct imports from the old paths will raise a DeprecationWarning and may break in future versions.
- gotcha By default, `flatten()` uses an underscore (`_`) as a delimiter and automatically enumerates items in lists/tuples. This might not be the desired key format, especially if keys already contain underscores or you prefer a different delimiter like a dot (`.`).
- gotcha The `enumerate_types` parameter in `flatten()` (defaulting to `(list, tuple)`) will turn list/tuple indices into parts of the flattened key (e.g., `products_0_id`). If you want to prevent enumeration for certain types or handle them differently, you need to adjust this parameter.
- gotcha For Python versions prior to 3.8, `importlib-metadata` is a required dependency to ensure good import performance. While `pathlib2` is optional for Python < 3.4, not having these can lead to slower performance or potentially missed functionality on older Python versions.
Install
-
pip install flatten-dict
Imports
- flatten
from flatten_dict import flatten
- unflatten
from flatten_dict import unflatten
- make_splitter
from flatten_dict.splitter import make_splitter
from flatten_dict.splitters import make_splitter
- make_reducer
from flatten_dict.reducer import make_reducer
from flatten_dict.reducers import make_reducer
Quickstart
from flatten_dict import flatten, unflatten
data = {
'user': {
'name': 'Alice',
'address': {'city': 'Wonderland', 'zip': '12345'}
},
'products': [
{'id': 1, 'item': 'Tea Cup'},
{'id': 2, 'item': 'Rabbit Hole'}
]
}
# Flatten the dictionary with default underscore delimiter
flat_data = flatten(data)
print('Flattened (default underscore):')
print(flat_data)
# Expected: {'user_name': 'Alice', 'user_address_city': 'Wonderland', 'user_address_zip': '12345', 'products_0_id': 1, 'products_0_item': 'Tea Cup', 'products_1_id': 2, 'products_1_item': 'Rabbit Hole'}
# Unflatten it back
unflat_data = unflatten(flat_data)
print('\nUnflattened back:')
print(unflat_data)
# Expected: {'user': {'name': 'Alice', 'address': {'city': 'Wonderland', 'zip': '12345'}}, 'products': [{'id': 1, 'item': 'Tea Cup'}, {'id': 2, 'item': 'Rabbit Hole'}]}
# Flatten with a custom dot delimiter
from flatten_dict.splitters import dot_splitter
flat_data_dot = flatten(data, splitter=dot_splitter)
print('\nFlattened (dot splitter):')
print(flat_data_dot)
# Expected: {'user.name': 'Alice', 'user.address.city': 'Wonderland', 'user.address.zip': '12345', 'products.0.id': 1, 'products.0.item': 'Tea Cup', 'products.1.id': 2, 'products.1.item': 'Rabbit Hole'}