Skip to content

Instantly share code, notes, and snippets.

@av1m
Last active May 30, 2022 09:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save av1m/3517b2eff6615c7c12a6cb31aa86fe5d to your computer and use it in GitHub Desktop.
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
"""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
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment