简体   繁体   中英

Get all unique combinations from list of permutations

TL/DR

Given X = {(A,B),(B,C),(D,E),(B,A),(C,B)} (where X is a set )

How do I filter for the subtuples which show a unique combination (instead of a unique permutation) such that X becomes {(A,B),(B,C),(D,E))}

Longer form

Somewhat of an inverse problem from most of the combination/permutation questions on here.

I have a set of tuples (outer tuples), where each tuple has 2 elements, both of which are also tuples (inner tuples), and each sub-tuple has two elements, both of which are integers.

As an example, the set with three elements might look like

X = { ( (1,2),(2,3) ), ( (1,3),(1,2) ), ( (2,3),(1,2) ) }

While all the outer tuples are unique, I'd like to build a subset which contains the set of unqiue tuples where the ORDER of the two inner tuples is irrelevant (ie a set of unique combinations). In the example above this would reduce to;

X = { ( (1,2),(2,3) ), ( (1,3),(1,2) )}

Because

( (1, 2),(2,3) ) and ( (2,3),(1,2) ) )

are both just combinations of (1, 2) and (2,3) .

There are obvious brute-force/for-loop approaches to this but they don't feel very Pythonic.

Maybe leveraging itertools and map ?

You can apply the sorted function on your elements using map and then use a set comprehension to get the unique elements :

>>> new={tuple(i) for i in map(sorted,X)}
>>> new
set([('B', 'C'), ('A', 'B'), ('D', 'E')])

But note that since sorted convert your elements to list you need to reverse them to tuple because lists are not hashable.

One way would be to sort the tuples, then make a new set. (A, B) and (B, A) will both have been sorted to (A, B), and thus only occur once.

def to_sorted(t):
    return tuple(sorted(t))

Xnew = {to_sorted(t) for t in X}

Another is to not use tuples at all -- tuples are ordered, and you don't care about the order. You could use sets. frozensets are immutable sets that can be elements of other sets:

Xnew = {frozenset(t) for t in X}

I like this slightly better, but 1) it doesn't work if your tuples contain multiples, and 2) now you have frozensets instead of tuples, your other code probably needs changing.

进一步简化了一个步骤(删除地图):

new = {tuple(sorted(n)) for n in X}

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