Reputation: 160
I have two lists:
list1=['a', 'z', 'd', 'e','b']
list2=['d','e', 'b' ]
and I need the combinations (not permutations) of the elements of these two lists. I have tried itertools.combinations
and itertools.product
, but I am not getting exactly what I want. For example, ('d','d')
would be wrong. ('a','z')
would also be wrong because 'a'
and 'z'
belong to the same list (list1
) and neither one of them appears in list2
. Finally, I do not want both ('d','e')
and ('e','d')
- only one of these pairs, since order does not matter. The ideal output would be:
('a','d'), ('a','e'), ('a','b'),
('z','d'), ('z','e'), ('z','b'),
('d','e'), ('d','b'), ('e','b')
Edit: generally, list2
will not always be a subset of list1
, but I want to handle that case as well. There could also be an overlap of these two lists and not a full subset.
Upvotes: 3
Views: 1053
Reputation: 8378
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))]
Then,
>>> print(a)
[('b', 'a'), ('b', 'z'), ('e', 'a'), ('e', 'z'), ('d', 'a'), ('d', 'z'), ('b', 'e'), ('b', 'd'), ('e', 'd')]
Upvotes: 1
Reputation: 42411
You can deal with examples like ('d', 'e')
and ('e', 'd')
by sorting the inner tuples:
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])
Upvotes: 1
Reputation: 131
Nonefficient way, but working :
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')}
I realy prefer @jpp solution !
Upvotes: 0
Reputation: 164673
Since order does not matter, you should use set
or frozenset
for order-agnostic collections.
One brute-force solution is to utilise itertools.product
, but use set
combined with a list comprehension to remove duplicates:
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'})]
Upvotes: 2
Reputation: 18208
May be not most efficient but you can try following:
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)
Result:
[('a', 'd'), ('a', 'e'), ('a', 'b'),
('z', 'd'), ('z', 'e'), ('z', 'b'),
('d', 'e'), ('d', 'b'), ('e', 'b')]
Upvotes: 2