Вы ищете набор пересечений из продукта ваших «меток», где каждая пара сама является набором (порядок не важно, если 2-4
и 4-2
считаются одинаковыми).
Пересечения наиболее эффективно тестируются с типом Python set
, поэтому при построении этих словарей можно преобразовать их нужно настроить вперед.
Поэтому нам нужны уникальные метки и способ поиска связанного списка для каждой метки. Это работа для словарей, поэтому сначала преобразуйте свои списки в словари и получите объединение их ключей. Затем превратите каждую пару в набор, чтобы {'2', '4'}
и {'4', '2'}
выглядели одинаково, сохраняя результаты в другом наборе. Обратите внимание, что 2-2
становится 2
в этом сценарии, поскольку набор будет хранить '2'
только один раз.
Тогда все, что нам нужно сделать, это проверить, есть ли пересечение между двумя списками, связанными с выбрал комбинацию клавиш и включил эту комбинацию, если есть:
from itertools import product
dict1 = {k: set(l) for k, l in list1}
dict2 = {k: set(l) for k, l in list2}
keys = dict1.keys() | dict2.keys() # all unique keys in both
found = {
frozenset((k1, k2))
for k1, k2 in product(keys, repeat=2)
if dict1.get(k1, set()) & dict2.get(k2, set())
}
Демо:
>>> from itertools import product
>>> dict1 = {k: set(l) for k, l in list1}
>>> dict2 = {k: set(l) for k, l in list2}
>>> keys = dict1.keys() | dict2.keys() # all unique keys in both
>>> {
... frozenset((k1, k2))
... for k1, k2 in product(keys, repeat=2)
... if dict1.get(k1, set()) & dict2.get(k2, set())
... }
{frozenset({'3', '4'}), frozenset({'2'}), frozenset({'3', '5'}), frozenset({'2', '5'}), frozenset({'2', '3'}), frozenset({'2', '4'}), frozenset({'1', '3'})}
Если у вас должны быть дублированные ссылки, вы можете постобработать результат:
for combo in found:
try:
a, b = combo
except ValueError: # doesn't contain 2 values, assume 1
a, = b, = combo
print(f'{a}-{b}')
Порядок будет зависеть от текущего случайного числа ha sh seed, поэтому вы можете использовать сортировку. Я получаю этот вывод:
3-4
2-2
3-5
2-5
2-3
2-4
1-3