如何使列表在 Python 中只包含不同的元素?

我有一个 Python 中的列表,如何使它的值惟一?

341775 次浏览

最简单的方法是转换成一个集合,然后返回到一个列表:

my_list = list(set(my_list))

这样做的一个缺点是无法保持订单。您可能还需要首先考虑一个集合是否比列表更适合使用。

来自 http://www.peterbe.com/plog/uniqifiers-benchmark:

def f5(seq, idfun=None):
# order preserving
if idfun is None:
def idfun(x): return x
seen = {}
result = []
for item in seq:
marker = idfun(item)
# in old Python versions:
# if seen.has_key(marker)
# but in new ones:
if marker in seen: continue
seen[marker] = 1
result.append(item)
return result

为了维持秩序:

l = [1, 1, 2, 2, 3]
result = list()
map(lambda x: not x in result and result.append(x), l)
result
# [1, 2, 3]

如果列表中的所有元素都可以用作字典键(例如,它们都是散列的) ,这通常会更快。Python 编程常见问题解答

d = {}
for x in mylist:
d[x] = 1
mylist = list(d.keys())

http://www.peterbe.com/plog/uniqifiers-benchmark的修改版本

为了维持秩序:

def f(seq): # Order preserving
''' Modified version of Dave Kirby solution '''
seen = set()
return [x for x in seq if x not in seen and not seen.add(x)]

好了,现在它是怎么工作的,因为这里有点棘手 if x not in seen and not seen.add(x):

In [1]: 0 not in [1,2,3] and not print('add')
add
Out[1]: True

为什么它返回 True? print (和 set.add)不返回任何值:

In [3]: type(seen.add(10))
Out[3]: <type 'NoneType'>

以及 not None == True,但是:

In [2]: 1 not in [1,2,3] and not print('add')
Out[2]: False

为什么它在[1]中打印“ add”而在[2]中不打印?请参阅 False and print('add'),并且不检查第二个参数,因为它已经知道答案,并且只有当两个参数都为 True 时才返回 True。

更通用、更易读、基于生成器的版本增加了用函数转换值的能力:

def f(seq, idfun=None): # Order preserving
return list(_f(seq, idfun))


def _f(seq, idfun=None):
''' Originally proposed by Andrew Dalke '''
seen = set()
if idfun is None:
for x in seq:
if x not in seen:
seen.add(x)
yield x
else:
for x in seq:
x = idfun(x)
if x not in seen:
seen.add(x)
yield x

没有秩序(它更快) :

def f(seq): # Not order preserving
return list(set(seq))

在保持顺序的同时删除重复项的最简单方法是使用 收藏品(Python 2.7 +)。

from collections import OrderedDict
d = OrderedDict()
for x in mylist:
d[x] = True
print d.iterkeys()

字典理解呢?

>>> mylist = [3, 2, 1, 3, 4, 4, 4, 5, 5, 3]


>>> {x:1 for x in mylist}.keys()
[1, 2, 3, 4, 5]

剪辑 在@Danny 的评论中: 我的原始建议是不保持钥匙的顺序。如果你需要把钥匙排序,试试:

>>> from collections import OrderedDict


>>> OrderedDict( (x,1) for x in mylist ).keys()
[3, 2, 1, 4, 5]

它通过元素的第一次出现来保持元素的顺序(未经过广泛测试)

一行程序和维护秩序

list(OrderedDict.fromkeys([2,1,1,3]))

尽管你需要

from collections import OrderedDict

让我用一个例子向你们解释:

如果你有 Python 列表

>>> randomList = ["a","f", "b", "c", "d", "a", "c", "e", "d", "f", "e"]

你想从中删除副本。

>>> uniqueList = []


>>> for letter in randomList:
if letter not in uniqueList:
uniqueList.append(letter)


>>> uniqueList
['a', 'f', 'b', 'c', 'd', 'e']

这就是从列表中删除重复项的方法。

Python 中集合的特征是集合中的数据项 是无序的,不允许重复。如果尝试向已经包含该数据项的集合中添加数据项,Python 将忽略该数据项。

>>> l = ['a', 'a', 'bb', 'b', 'c', 'c', '10', '10', '8','8', 10, 10, 6, 10, 11.2, 11.2, 11, 11]
>>> distinct_l = set(l)
>>> print(distinct_l)
set(['a', '10', 'c', 'b', 6, 'bb', 10, 11, 11.2, '8'])