Комбинация между списками, игнорирующими элементы внутри и list и игнорирующими упорядочение пар - PullRequest
0 голосов
/ 28 мая 2018

У меня есть два списка:

list1=['a', 'z', 'd', 'e','b']
list2=['d','e', 'b' ]

и мне нужны комбинации (не перестановки) элементов этих двух списков.Я пробовал itertools.combinations и itertools.product, но я не получаю именно то, что хочу.Например, ('d','d') будет неправильно.('a','z') также будет неправильным, поскольку 'a' и 'z' принадлежат одному и тому же списку (list1), и ни один из них не появляется в list2.Наконец, я не хочу, чтобы и ('d','e'), и ('e','d') - только одна из этих пар, поскольку порядок не имеет значения.Идеальный результат будет выглядеть так:

('a','d'), ('a','e'), ('a','b'),
('z','d'), ('z','e'), ('z','b'),
('d','e'), ('d','b'), ('e','b')

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

Ответы [ 5 ]

0 голосов
/ 28 мая 2018

С примерами типа ('d', 'e') и ('e', 'd') можно разобраться, отсортировав внутренние кортежи:

from itertools import product

xs = ['a', 'z', 'd', 'e', 'b']
ys = ['d', 'e', 'b']

got = set(tuple(sorted(t)) for t in product(xs, ys) if t[0] != t[1])
0 голосов
/ 28 мая 2018

Неэффективный способ, но работает:

print(set([z for x in list1 for z in [tuple(x+y) if ord(x) < ord(y) else tuple(y+x) for y in list2 if x != y]]))

{('a', 'e'), ('e', 'z'), ('b', 'z'), («d», «e»), («a», «b»), («b», «d»), («b», «e»), («d», «z»), ('a', 'd')}

Я действительно предпочитаю решение @jpp!

0 голосов
/ 28 мая 2018

Может быть не самым эффективным, но вы можете попробовать следующее:

list1=['a', 'z', 'd', 'e','b']
list2=['d','e', 'b' ]

result = []
for i in list1:
    for j in list2:
        if i != j and (j,i) not in result:
            result.append((i,j))
print(result)

Результат:

[('a', 'd'), ('a', 'e'), ('a', 'b'), 
 ('z', 'd'), ('z', 'e'), ('z', 'b'), 
 ('d', 'e'), ('d', 'b'), ('e', 'b')]
0 голосов
/ 28 мая 2018
from itertools import chain, product, combinations
common = set(list1) & set(list2)
sdiff = set(list1) ^ set(list2)
result = [i for i in chain(product(common, sdiff), combinations(common, 2))]

Тогда

>>> print(a)
[('b', 'a'), ('b', 'z'), ('e', 'a'), ('e', 'z'), ('d', 'a'), ('d', 'z'), ('b', 'e'), ('b', 'd'), ('e', 'd')]
0 голосов
/ 28 мая 2018

Так как порядок не имеет значения, вы должны использовать set или frozenset для коллекций, не зависящих от порядка.

Одно из методов перебора - использовать itertools.product, но использовать set в сочетании спонимание списка для удаления дубликатов:

from itertools import product

list1=['a', 'z', 'd', 'e','b']
list2=['d','e', 'b' ]

res = [i for i in set(map(frozenset, product(list1, list2))) if len(i) > 1]

print(res)

[frozenset({'b', 'e'}),
 frozenset({'a', 'e'}),
 frozenset({'d', 'z'}),
 frozenset({'b', 'd'}),
 frozenset({'a', 'd'}),
 frozenset({'d', 'e'}),
 frozenset({'b', 'z'}),
 frozenset({'a', 'b'}),
 frozenset({'e', 'z'})]
...