Найти ключ, если значение существует во вложенном словаре - PullRequest
0 голосов
/ 05 июня 2018

Я работаю с Python 3.6, и мне нужно перебрать вложенный словарь, чтобы найти, существует ли указанное значение, и, если это так, сохранить все ключи, которые соответствуют этому значению.Мне также нужно расширить эти критерии, чтобы иметь возможность хранить ключи, для которых существует определенное значение для указанного ключа словаря.

Словарь построен следующим образом:

dict = {A: {B: [a, b, c], C: [d, c, e]}, D: {B: [f, g, h], E: [i, j, c]}...}

Каждыйпервичный ключ (A, D и т. д.) уникален, но ключи в под-словарях повторяются в разных под-словарях.

Я хотел бы получить все первичные ключи, для которых существует значение, такое как "c", поэтому вывод будет:

foundKeys = [A, D]

Я также хотел бы добавить критерии дляключ под-словаря, например, получить все первичные ключи, для которых "c" существует для ключа под-словаря "B".Здесь вывод будет:

foundKeys = [A]

Что касается первого условия, я придумал следующий код:

myList = list(dict.keys())

foundKeys = []

for i in range(0,len(myList)):
    tmpList = list(dict.get(myList[i],{}).values())
    for j in range(0, len(tmpList)):
        for k in range(0, len(tmpList[j])):
            if "c" in tmpList[j][k]:
                if myList[i] not in foundKeys:
                    foundKeys.append(myList[i])

Это позволяет мне получить список всех ключей, которыеимеют соответствующее значение «c» ([A, D]), но у меня большой набор данных, и я понимаю, что, вероятно, есть лучший способ справиться с этим.

Я мог бы изменить этот код, чтобы добавить подпрограммуусловие для словаря и получить вывод [A], но для его запуска потребуется еще больше времени.

Я новичок в Python и все еще учусь оптимизировать.Можете ли вы посоветовать, как мне подойти к этому, чтобы лучше справиться с этим при работе с большим набором данных?

Ответы [ 5 ]

0 голосов
/ 05 июня 2018

Вы можете использовать рекурсию для обработки ввода произвольной глубины:

d1 = {'A': {'B': ['a', 'b', 'c'], 'C': ['d', 'c', 'e']}, 'D': {'B': ['f', 'g', 'h'], 'E': ['i', 'j', 'c']}}
def get_keys(d, to_find):
  for a, b in d.items():
     if to_find in b:
       yield a
     if isinstance(b, dict):
       yield from get_keys(b, to_find)

print(list(get_keys(d1, 'c')))

Вывод:

['B', 'C', 'E']
0 голосов
/ 05 июня 2018

Если вы собираетесь выполнить много поисков такого рода, небольшая предварительная обработка будет иметь большое значение.

Возьмите словарь, который вы представили в своем вопросе:

dict = { A: { B: [a, b, c] 
            , C: [d, c, e]
            } 
       , D: { B: [f, g, h]
            , E: [i, j, c]
            }
       }

Вы можете пройти через каждую пару ключ-значение и создать что-то вроде

new_dict = { a: { A: {B, C}
                , D: {E}
                }
           , b: { A: {B} 
                }
           , c: { A: {B, C}
                , D: {E}
                } 
           , d: { A: {C}
                }
           , e: { A: {C}
                }
           , f: { D: {B}
                }
           , g: { D: {B}
                }
           , h: { D: {B}
                }
           , i: { D: {E}
                }
           , j: { D: {E}
                }
           }

В приведенном выше словаре каждое из значений из исходного словаря dict является ключом.Каждый из них связан со своим собственным словарем, где ключи - это ключи верхнего уровня из исходного словаря, а значения - это наборы ключей из под-словарей.

Это может быть много работы заранее, но это должно сэкономить ваше время, когда вы выполняете повторный поиск того типа, который вы упомянули.

0 голосов
/ 05 июня 2018

Вы можете сделать это более коротко с помощью чего-то вроде этого:

>>> result = []
>>> for key, subdict in d.items():
...     for sublist in subdict.values():
...         if "c" in sublist:
...             result.append(key)
...             break
... 
>>> print(result)
['A', 'D']

Обратите внимание на использование items и values в качестве способа перебора элементов dict.

0 голосов
/ 05 июня 2018

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

d = {'A': {'B': ['a', 'b', 'c'], 'C': ['d', 'c', 'e']}, 'D': {'B': ['f', 'g', 'h'], 'E': ['i', 'j', 'c']}}

found_keys = [k for k, v in d.items() if any("c" in l for l in v.values())]

Если вы хотите фильтровать по ключу subdictionary, он еще короче:

found_keys = [k for k, v in d.items() if "c" in v['B']]
0 голосов
/ 05 июня 2018

Вы можете использовать встроенные .keys() и .values() для непосредственного извлечения ключей и значений соответственно.

Код:

dict = {'A': {'B': ['a', 'b', 'c'], 'C': ['d', 'c', 'e']}, 'D': {'B': ['f', 'g', 'h'], 'E': ['i', 'j', 'c']}}

listOfKeys = []
for i in dict.keys():
    for j in dict[i].values():
        if 'c' in j:
            if i not in listOfKeys:
                listOfKeys.append(i)

print(listOfKeys)

Выход:

['A', 'D']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...