在 python 列表中获取唯一的元组,而不管顺序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35975441/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 17:13:45  来源:igfitidea点击:

Grab unique tuples in python list, irrespective of order

pythonlistnumpyduplicates

提问by Christopher

I have a python list:

我有一个 python 列表:

[ (2,2),(2,3),(1,4),(2,2), etc...]

What I need is some kind of function that reduces it to its unique components... which would be, in the above list:

我需要的是某种功能,将其减少到其独特的组件......这将是,在上面的列表中:

[ (2,2),(2,3),(1,4) ]


numpy unique does not quite do this. I can think of a way to do it--convert my tuples to numbers, [22,23,14,etc.], find the uniques, and work back from there...but I don't know if the complexity won't get out of hand. Is there a function that will do what I am trying to do with tuples?

numpy unique 并没有完全做到这一点。我可以想出一种方法——将我的元组转换为数字,[22,23,14,etc.]找到唯一值,然后从那里开始工作……但我不知道复杂性是否会失控。有没有一个函数可以做我想要对元组做的事情?



Here is a sample of code that demonstrates the problem:

这是演示问题的代码示例:

 import numpy as np

 x = [(2,2),(2,2),(2,3)]
 y = np.unique(x)

returns: y: [2 3]

返回:y:[2 3]

And here is the implementation of the solution that demonstrates the fix:

这是演示修复的解决方案的实现:

 x = [(2,2),(2,2),(2,3)]
 y = list(set(x))

returns y: [(2,2),(2,3)]

返回 y: [(2,2),(2,3)]

采纳答案by Mehdi Golari

you could simply do

你可以简单地做

y = np.unique(x, axis=0)
z = [] 
for i in y:
   z.append(tuple(i))

The reason is that a list of tuples is interpreted by numpy as a 2D array. By setting axis=0, you'd be asking numpy not to flatten the array and return unique rows.

原因是元组列表被 numpy 解释为二维数组。通过设置轴 = 0,您会要求 numpy 不要展平数组并返回唯一的行。

回答by timgeb

If order does not matter

如果顺序无关紧要

If the order of the result is not critical, you can convert your list to a set (because tuples are hashable) and convert the set back to a list:

如果结果的顺序不重要,您可以将列表转换为集合(因为元组是可散列的)并将集合转换回列表:

>>> l = [(2,2),(2,3),(1,4),(2,2)]
>>> list(set(l))
[(2, 3), (1, 4), (2, 2)]

If order matters

如果订单很重要

(UPDATE)

(更新)

As of CPython 3.6 (or any Python 3.7 version) regular dictionaries remember their insertion order, so you can simply issue.

从 CPython 3.6(或任何 Python 3.7 版本)开始,常规词典会记住它们的插入顺序,因此您可以简单地发出。

>>> l = [(2,2),(2,3),(1,4),(2,2)]
>>> list(dict.fromkeys(l))
[(2, 2), (2, 3), (1, 4)]


(OLD ANSWER)

(旧答案)

If the order is important, the canonical way to filter the duplicates is this:

如果顺序很重要,则过滤重复项的规范方法是:

>>> seen = set()
>>> result = []
>>> for item in l:
...     if item not in seen:
...         seen.add(item)
...         result.append(item)
... 
>>> result
[(2, 2), (2, 3), (1, 4)]

Finally, a little slower and a bit more hackish, you can abuse an OrderedDictas an ordered set:

最后,稍微慢一点,更hackish,你可以滥用 anOrderedDict作为一个有序集:

>>> from collections import OrderedDict
>>> OrderedDict.fromkeys(l).keys() # or list(OrderedDict.fromkeys(l)) if using a version where keys() does not return a list
[(2, 2), (2, 3), (1, 4)]

回答by Mureinik

Using a setwill remove duplicates, and you create a listfrom it afterwards:

使用 aset将删除重复项,然后您list从中创建一个:

>>> list(set([ (2,2),(2,3),(1,4),(2,2) ]))
[(2, 3), (1, 4), (2, 2)]

回答by zondo

set()will remove all duplicates, and you can then put it back to a list:

set()将删除所有重复项,然后您可以将其放回列表中:

unique = list(set(mylist))

Using set(), however, will kill your ordering. If the order matters, you can use a list comprehension that checks if the value already exists earlier in the list:

set()但是,使用会杀死您的订单。如果顺序很重要,您可以使用列表推导来检查该值是否已存在于列表的较早位置:

unique = [v for i,v in enumerate(mylist) if v not in mylist[:i]]

That solution is a little slow, however, so you can do it like this:

但是,该解决方案有点慢,因此您可以这样做:

unique = []
for tup in mylist:
    if tup not in unique:
        unique.append(tup)