I’m doing it a bit differently, using sets to get rid of the order where the order is not necessary. Actually using frozensets, so we can easily nest them.
First of all, we convert the lis
into a list of lists of (frozen)sets, because the order of the numbers of the tuples should be ignored.
>>> lis = [[(1,2), (3,4)], [(5,2), (1,2)], [(2,1), (1,2)]]
>>> lis_ = [[frozenset(x) for x in y] for y in lis]
Next, we create the product, and then put the result in a set, so we get rid of duplicates:
>>> result = set(x for x in itertools.product(*lis_))
>>> result
{(frozenset({3, 4}), frozenset({1, 2}), frozenset({1, 2})), (frozenset({1, 2}), frozenset({1, 2}), frozenset({1, 2})), (frozenset({3, 4}), frozenset({2, 5}), frozenset({1, 2})), (frozenset({1, 2}), frozenset({2, 5}), frozenset({1, 2}))}
And we are already done. If you print those now, and make it a bit prettier (getting rid of the frozenset()
part in the output, you have your result:
>>> for r in result:
print([tuple(x) for x in r])
[(3, 4), (1, 2), (1, 2)]
[(1, 2), (1, 2), (1, 2)]
[(3, 4), (2, 5), (1, 2)]
[(1, 2), (2, 5), (1, 2)]
Different solution which just filters the results from itertools.product
:
>>> lis = [[(1,2), (3,4)], [(5,2), (1,2)], [(2,1), (1,2)]]
>>> seenProducts = set()
>>> for p in itertools.product(*lis):
product = tuple(frozenset(x) for x in p)
if product not in seenProducts:
seenProducts.add(product)
print(p) # print original product
((1, 2), (5, 2), (2, 1))
((1, 2), (1, 2), (2, 1))
((3, 4), (5, 2), (2, 1))
((3, 4), (1, 2), (2, 1))