CTKlein
CTKlein

Reputation: 309

Heterogeneous combinations between two lists

What's a better way to generate unique combinations of pairs between two lists where pairs must also be heterogeneous (i.e. pair[0] != pair[1])? By combinations, I mean that I only want one copy of (2, 1) and (1, 2). (is there a better way to express this?)

For example:

a = [1, 4]  
b = [1, 2, 3]  
magic_functions(a, b)  

should return:

[(1, 2), (4, 2), (1, 3), (4, 1), (4, 3)]

I can get there using the following but it seems a bit cumbersome:

prod = itertools.product(a, b)
pairs = set()
for x, y in prod:
    if x != y and (y, x) not in pairs:
        pairs.add((x, y))

Upvotes: 0

Views: 831

Answers (2)

Ashwini Chaudhary
Ashwini Chaudhary

Reputation: 250951

You can use frozenset instead of tuple, a frozenset is immmutable so can be stored in a set:

>>> for x, y in prod:
        if x != y:
           pairs.add(frozenset((x, y)))

>>> pairs
set([frozenset([1, 3]), frozenset([1, 2]), frozenset([2, 3])])

You can easily extend this to store more than just pairs, for example if we had triads then checking for all of the unique combinations of it in the set will be cumbersome, but frozenset makes it easy:

>>> c = [7, 8, 9]
>>> prod = itertools.product(a, b, c)
>>> triplets = set()
>>> for p in prod:
...     f = frozenset(p)
...     if len(f) == 3:
...         triplets.add(f)
...         
>>> triplets
set([frozenset([1, 3, 7]), frozenset([1, 2, 9]), frozenset([8, 1, 2]), frozenset([2, 3, 7]), frozenset([8, 1, 3]), frozenset([1, 2, 7]), frozenset([9, 2, 3]), frozenset([8, 2, 3]), frozenset([1, 3, 9])])

Upvotes: 5

Daniel
Daniel

Reputation: 5381

You can use the itertools chain and combinations functions

import itertools
a = [1, 2]  
b = [1, 2, 3]  
q = set(itertools.chain(a,b))
w = list(itertools.combinations(q,2))
print w

which returns

[(1, 2), (1, 3), (2, 3)]

Upvotes: 2

Related Questions