Last active
May 30, 2022 09:19
-
-
Save av1m/3517b2eff6615c7c12a6cb31aa86fe5d 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 hidden or 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. | |
To get better performance, it's recommended to use a list rather than a string for the map_list argument. | |
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