如何在Python中创建仅包含不同元素的列表?
我在Python里有一个列表,我该怎么让里面的值变得唯一呢?
10 个回答
31
一行代码并保持顺序
list(OrderedDict.fromkeys([2,1,1,3]))
不过你需要
from collections import OrderedDict
33
修改版的 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?打印(以及 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))
393
最简单的方法是先把列表转换成集合,然后再转换回列表:
my_list = list(set(my_list))
不过这样做有个缺点,就是它不会保留原来的顺序。你也可以考虑一下,直接用集合作为数据结构是否更合适,而不是用列表。