-
-
Save wojtha/f792a2095f799a9e6bd6e66c43abe6e9 to your computer and use it in GitHub Desktop.
Crosses a list or dictionary in an elegant way using list or str as key
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""Utility functions""" | |
from functools import reduce | |
from operator import getitem | |
from typing import Any, Mapping, Union | |
def getdeep(data: Mapping, map_list: Union[list, str], default: Any = None) -> Any: | |
"""Iterate nested dictionary|list and can return default value if key not found | |
This methods can handle list of keys as well as string of keys separated by dot. | |
Example: | |
>>> data = {'a': {'b': {'c': 1}}} | |
>>> getdeep(data, ['a', 'b', 'c']) | |
1 | |
>>> getdeep(data, 'a.b.c') | |
1 | |
>>> getdeep(data, ['a', 'b', 'D'], default=0) | |
0 | |
>>> getdeep(data, 'a.b.D', default=0) | |
0 | |
>>> getdeep({data: ["a", "b", "c"]}, "data.1") | |
'b' | |
>>> getdeep({data: ["a", "b", "c"]}, ["data", 1]) | |
'b' | |
>>> getdeep(["a": {"j": "e"} "b", "c"], ["0.j"]) | |
'e' | |
:param data: dictionary or list to iterate | |
:type data: Mapping | |
:param map_list: list of keys or string of keys separated by dot | |
:type map_list: list or str | |
:param default: default value to return if key not found | |
:type default: Any | |
:return: value of key or default value | |
:rtype: Any | |
""" | |
try: | |
if isinstance(map_list, str): | |
map_list = map_list.split(".") | |
# Transform string integer keys to int | |
map_list = [ | |
int(key) if isinstance(key, str) and key.isdigit() else key | |
for key in map_list | |
] | |
return reduce(getitem, map_list, data) | |
except (KeyError, IndexError, TypeError): | |
return default |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment