Python: Generating a “set of tuples” from a “list of tuples” that doesn't take order into consideration

冷暖自知 提交于 2019-12-17 20:48:10

问题


If I have the list of tuples as the following:

[('a', 'b'), ('c', 'd'), ('a', 'b'), ('b', 'a')]

I would like to remove duplicate tuples (duplicate in terms of both content and order of items inside) so that the output would be:

[('a', 'b'), ('c', 'd')]

Or

[('b', 'a'), ('c', 'd')]

I tried converting it to set then to list but the output would maintain both ('b', 'a') and ('a', 'b') in the resulting set!


回答1:


Try this :

a = [('a', 'b'), ('c', 'd'), ('a', 'b'), ('b', 'a')]
b = list(set([ tuple(sorted(t)) for t in a ]))
[('a', 'b'), ('c', 'd')]

Let's break this down :

If you sort a tuple, it becomes a sorted list.

>>> t = ('b', 'a')
>>> sorted(t)
['a', 'b']

For each tuple t in a, sort it and convert it back to a tuple.

>>> b = [ tuple(sorted(t)) for t in a ]
>>> b
[('a', 'b'), ('c', 'd'), ('a', 'b'), ('a', 'b')]

Convert the resulting list b to a set : values are now unique. Convert it back to a list.

>>> list(set(b))
[('a', 'b'), ('c', 'd')]

Et voilà !

Note that you can skip the creation of the intermediate list b by using a generator instead of a list comprehension.

>>> list(set(tuple(sorted(t)) for t in a))
[('a', 'b'), ('c', 'd')]



回答2:


If you did not mind using a frozenset with a set:

l = [('a', 'b'), ('c', 'd'), ('a', 'b'), ('b', 'a')]

print(set(map(frozenset,l)))
{frozenset({'a', 'b'}), frozenset({'c', 'd'})}

You can convert back to tuple if preferable:

l = [('a', 'b'), ('c', 'd'), ('a', 'b'), ('b', 'a')]

print(list(map(tuple,set(map(frozenset ,l)))))
[('a', 'b'), ('d', 'c')]

Or using a set and reversing the order of the tuples:

l = [('a', 'b'), ('c', 'd'), ('a', 'b'), ('b', 'a')]

seen, pairs = set(), []
for a,b in l:
    if (a,b) not in seen and (b,a) not in seen:
        pairs.append((a,b))
    seen.add((a,b))



回答3:


This can solve your problem if order is not important.

a=[('a', 'b'), ('c', 'd'), ('a', 'b'), ('b', 'a')]


a=map(tuple,[sorted(i) for i in a])

print list(set(a))

Output:

[('a', 'b'), ('c', 'd')]



回答4:


Built-in types to the rescue:

data = [('a', 'b'), ('c', 'd'), ('a', 'b'), ('b', 'a')]
set(map(frozenset, data))
{frozenset({'a', 'b'}), frozenset({'c', 'd'})}


来源:https://stackoverflow.com/questions/34052216/python-generating-a-set-of-tuples-from-a-list-of-tuples-that-doesnt-take-o

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!