Словарь Python, использующий списки в качестве значений, найти другие ключи с такими же значениями - PullRequest
0 голосов
/ 06 октября 2018

Скажем, у меня есть следующий словарь.

>> sample_dict = {"1": ['a','b','c'], "2": ['d','e','f'], "3": ['g','h','a']}

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

Например, она выдаст:

>> [["1","3"] , ['a']]

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

>> sample_dict = {"1": ['a','b','c'], "2": ['d','e','f'], "3": ['a','b','c']}

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

Ответы [ 4 ]

0 голосов
/ 06 октября 2018

Вы можете использовать defaultdict из collections модуля, чтобы сделать это

, например,

from collections import defaultdict
sample_dict = {"1": ['a','b','c'], "2": ['d','e','f'], "3": ['g','h','a']}

d = defaultdict(list)
for keys, vals in sample_dict.items():
    for v in vals:
        d[v].append(keys)


print(d)

d вернет dict, где ключи будут значениямикоторые повторяются, и значения будут списком, в котором они были повторены в

Вывод вышеуказанного кода будет defaultdict(list,{'a': ['1', '3'],'b': ['1'],'c': ['1'],'d': ['2'],'e': ['2'],'f': ['2'],'g': ['3'],'h': ['3']})

Хотя возможно получить форму, в которой вы хотели выводбыть в, но это обычно не рекомендуется, потому что мы пытаемся получить, какой символ повторяется в каком списке, это похоже на работу словаря

0 голосов
/ 06 октября 2018

Словари отображаются от ключей к значениям, а не от значений к ключам.Но вы можете написать функцию для разовых вычислений.Это повлечет за собой сложность времени O ( n ) и не рекомендуется для больших словарей:

def find_keys(d, val):
    return [k for k, v in d.items() if val in v]

res = find_keys(sample_dict, 'a')  # ['1', '3']

Если вы делаете это часто, я рекомендую вам "инвертировать" ваш словарь с помощью collections.defaultdict:

from collections import defaultdict

dd = defaultdict(list)

for k, v in sample_dict.items():
    for w in v:
        dd[w].append(k)

print(dd)

defaultdict(<class 'list'>, {'a': ['1', '3'], 'b': ['1'], 'c': ['1'], 'd': ['2'],
                             'e': ['2'], 'f': ['2'], 'g': ['3'], 'h': ['3']})

Это стоит O ( n ) для инверсии, а также дополнительной памяти, но теперь позволяет получить доступ к клавишам, связанным с входомзначение за O (1), например, dd['a'] вернет ['1', '3'].

0 голосов
/ 06 октября 2018

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

from collections import defaultdict

sample_dict = {'1': ['a','b','c'], '2': ['d','e','f'], '3': ['g','h','a']}    

d = defaultdict(list)  # automatically initialize every value to a list()

for k, v in sample_dict.items():
    for x in v:
        d[x].append(k)

for k, v in d.items():
    if len(v) > 1:
        print([v, k])

Выход:

[['1', '3'], 'a']
0 голосов
/ 06 октября 2018

Если элементы списка могут быть хэшируемыми, вы можете использовать .setdefault для построения обратного отображения следующим образом:

>>> sample_dict = {"1": ['a','b','c'], "2": ['d','e','f'], "3": ['g','h','a']}
>>> aux = {}
>>> for k, v in sample_dict.items():
...     for i in v:
...         aux.setdefault(i, []).append(k)
... 
>>> [[v, k] for k, v in aux.items() if len(v) > 1]
[[['1', '3'], 'a']]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...