Вложенные списки и словари в python - PullRequest
1 голос
/ 29 января 2020

У меня есть 3 разных словаря в python, подобных этим

d1 = {'simple_key':'hello'}
d2 = {'k1':{'k2':'hello'}}
d3 = {'k1':[{'nest_key':['this is deep',['hello']]}]}

, и я хочу взять слово "привет" из этих словарей. Но проблема, с которой я сталкиваюсь, заключается в том, что я хочу найти универсальный c способ его извлечения. Как я могу это сделать?

Ответы [ 3 ]

3 голосов
/ 29 января 2020

Чтобы получить путь ключа в dict, используя значение, вы можете сгладить его как json.

>>> from json_flatten import flatten
>>> d1 = {'simple_key':'hello'}
>>> d2 = {'k1':{'k2':'hello'}}
>>> d3 = {'k1':[{'nest_key':['this is deep',['hello']]}]}
>>> flatten(d2)
{'k1.k2': 'hello'}
>>> flat = flatten(d3)
{'k1.0.nest_key.0': 'this is deep', 'k1.0.nest_key.1.0': 'hello'}

Чтобы найти подходящие ключи, используйте,

>>> [k for k, v in flat.items() if v == 'hello']
['k1.0.nest_key.1.0']

JSON Свести

0 голосов
/ 29 января 2020

Вы можете создать свою собственную функцию выравнивания, которая возвращает значения в диктовке и членах списка:

def is_nonstring_iterable(x):
    return ((hasattr(x, "__iter__") or hasattr(x, "__getitem__")) 
        and not isinstance(x, str))

def flatten(thing):
    """ Recursively iterate through values in dictionary-like object or members 
        in lists, tuples or other non-string iterables """
    if hasattr(thing, "values"):
        thing = thing.values()
    if is_nonstring_iterable(thing):
        for element in thing:
            yield from flatten(element)
    else:
        yield thing

for d in [d1, d2, d3]:
    print(list(flatten(d)))
    print(any(item == "hello" for item in flatten(d))) # returns whether hello is found
0 голосов
/ 29 января 2020

Вы можете продолжать входить в словарь, пока не получите значение, а не словарь. Рекурсия была бы полезна здесь:

def get_value(dict):
     dict_value = list(dict.values())[0]
     if type(dict_value) is dict:
          get_value(dict_value)
     else: 
          return dict_value

, вероятно, есть более хороший способ сделать dict_value = list(dict.values())[0], но сейчас он не приходит в голову

...