Reputation: 309
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
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