Skip to content

Instantly share code, notes, and snippets.

@wojtha
Forked from av1m/getdeep.py
Created April 28, 2022 08:22
Show Gist options
  • Save wojtha/f792a2095f799a9e6bd6e66c43abe6e9 to your computer and use it in GitHub Desktop.
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
"""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
Display the source blob
Display the rendered blob
Raw
Loading
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