Последовательное разворачивание словарей и списков в Python

Зайчатки разума

Записная книжка айтишника

Последовательное разворачивание словарей и списков в 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

comments powered by Disqus