简体   繁体   中英

Unique permutations for a list of tuples

I want to produce something between a permutation and a combination for a list of tuples. If, for example, I have the list

list_of_tuples = [(1,20), (1,21), (2,18), (2,19)]

I want to create all possible "combinations" of 3 tuples so that I want the list to include the result [(1,20), (1,20), (1,20)] but I consider [(1,20), (1,20), (1,21)] to be identical to [(1,20), (1,21), (1,20)] and [(1,21), (1,20), (1,20)] and want to keep only one of these (doesn't matter which one).

In other words, if the "combination" includes the same tuples as another "combination", I don't want to keep the other one(s).

I've tried something like

list_of_lists = [list_of_tuples]*3
results = list(itertools.product(*list_of_lists))
results = set(results)

But by using set() I lose [(1,20), (1,20), (1,20)] and all the other results that have the same tuple three times.

Use itertools.combinations_with_replacement , which should produce exactly what you describe:

>>> from itertools import combinations_with_replacement
>>> list_of_tuples = [(1,20), (1,21), (2,18), (2,19)]
>>> list(combinations_with_replacement(list_of_tuples, 3))
[((1, 20), (1, 20), (1, 20)),
 ((1, 20), (1, 20), (1, 21)),
 ((1, 20), (1, 20), (2, 18)),
 ((1, 20), (1, 20), (2, 19)),
 ((1, 20), (1, 21), (1, 21)),
 ((1, 20), (1, 21), (2, 18)),
 ((1, 20), (1, 21), (2, 19)),
 ((1, 20), (2, 18), (2, 18)),
 ((1, 20), (2, 18), (2, 19)),
 ((1, 20), (2, 19), (2, 19)),
 ((1, 21), (1, 21), (1, 21)),
 ((1, 21), (1, 21), (2, 18)),
 ((1, 21), (1, 21), (2, 19)),
 ((1, 21), (2, 18), (2, 18)),
 ((1, 21), (2, 18), (2, 19)),
 ((1, 21), (2, 19), (2, 19)),
 ((2, 18), (2, 18), (2, 18)),
 ((2, 18), (2, 18), (2, 19)),
 ((2, 18), (2, 19), (2, 19)),
 ((2, 19), (2, 19), (2, 19))]

You could also try this:

from itertools import product
from collections import Counter

list_of_tuples = [(1,20), (1,21), (2,18), (2,19)]

list_of_lists = [list_of_tuples] * 3

seen = set()
unique = []

for prod in product(*list_of_lists):
    curr = frozenset(Counter(prod).items())

    if curr not in seen:
        seen.add(curr)
        unique.append(prod)

print(unique)

Which Outputs:

[((1, 20), (1, 20), (1, 20)), 
 ((1, 20), (1, 20), (1, 21)), 
 ((1, 20), (1, 20), (2, 18)), 
 ((1, 20), (1, 20), (2, 19)), 
 ((1, 20), (1, 21), (1, 21)), 
 ((1, 20), (1, 21), (2, 18)), 
 ((1, 20), (1, 21), (2, 19)), 
 ((1, 20), (2, 18), (2, 18)), 
 ((1, 20), (2, 18), (2, 19)), 
 ((1, 20), (2, 19), (2, 19)), 
 ((1, 21), (1, 21), (1, 21)), 
 ((1, 21), (1, 21), (2, 18)), 
 ((1, 21), (1, 21), (2, 19)), 
 ((1, 21), (2, 18), (2, 18)), 
 ((1, 21), (2, 18), (2, 19)), 
 ((1, 21), (2, 19), (2, 19)), 
 ((2, 18), (2, 18), (2, 18)), 
 ((2, 18), (2, 18), (2, 19)), 
 ((2, 18), (2, 19), (2, 19)), 
 ((2, 19), (2, 19), (2, 19))]

Are you looking something like this?

list_of_tuples = [(1,20), (1,21), (2,18), (2,19)]

import itertools

data=[]

for i in itertools.product(list_of_tuples,repeat=3):
    data.append(i)

dict_1=[]

for i in data:
    if sorted(i,key=lambda x:x[1]) not in dict_1:
        dict_1.append(sorted(i,key=lambda x:x[1]))

print(dict_1)

output:

[[(1, 20), (1, 20), (1, 20)], [(1, 20), (1, 20), (1, 21)], [(2, 18), (1, 20), (1, 20)], [(2, 19), (1, 20), (1, 20)], [(1, 20), (1, 21), (1, 21)], [(2, 18), (1, 20), (1, 21)], [(2, 19), (1, 20), (1, 21)], [(2, 18), (2, 18), (1, 20)], [(2, 18), (2, 19), (1, 20)], [(2, 19), (2, 19), (1, 20)], [(1, 21), (1, 21), (1, 21)], [(2, 18), (1, 21), (1, 21)], [(2, 19), (1, 21), (1, 21)], [(2, 18), (2, 18), (1, 21)], [(2, 18), (2, 19), (1, 21)], [(2, 19), (2, 19), (1, 21)], [(2, 18), (2, 18), (2, 18)], [(2, 18), (2, 18), (2, 19)], [(2, 18), (2, 19), (2, 19)], [(2, 19), (2, 19), (2, 19)]]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM