Последовательное разворачивание словарей и списков в Python
2021-03-03 01:50:40 —
Evgeniy Shumilov
Бывают такие вещи, до которых постоянно не доходят руки и это одна из них. Если у нас есть объект большой вложенности, то мы не можем в python, как скажем, в java извлечь нужное значение, указав объект и последовательность его ключей. Нам приходится двигаться последовательно вглубь объекта, проверяя наличие нужного нам ключа на каждом уровне вложенности, а то и тип самого объекта. Решения существуют, но в виде отдельных библиотек - pydash, dictor и, вероятно, каких-то иных, которые необходимо ставить отдельно. Не люблю лишние зависимости, если вместо них можно обойтись десятком строк.
Собственно, вот они, в комментарии можно увидеть примеры использования:
def getval(obj, *keys):
'''
GetValue from object by keys list
Example:
>>> test = {'a': {'b': {'c': [1,2,3]}}}
>>> getval(test, 'a', 'b', 'c')
[1, 2, 3]
>>> getval(test, 'a', 'b', 'c', -1)
3
>>> getval(test, 'a', 'b', 'd')
>>>
>>> getval(test, 'a', 'b', 'c', 4)
>>>
'''
if type(obj) not in (tuple, list, dict):
raise AttributeError('getval() expects dict, list or tuple as first argument.')
if len(keys) == 0:
raise AttributeError('getval() expects at least two arguments, one given.')
_obj = obj
for key in keys:
try:
if type(_obj) in (tuple, list):
if not isinstance(key, int) or key < -len(_obj) or key >= len(_obj) and not len(_obj):
return None
elif isinstance(_obj, dict):
_obj = _obj[key]
else:
return None
except KeyError:
return None
return _obj
Теги: python