例如:
>>> a
[2, -4, -2, 4, -3, -1, 3, 4, 2, 2]
>>> unique(a)
[2, 3, 4, -2, -4, -3, -1]
它给了我一个值列表,每个值只出现一次,但我希望它也以与原始列表相同的顺序打印它们。
例如:
>>> a
[2, -4, -2, 4, -3, -1, 3, 4, 2, 2]
>>> unique(a)
[2, 3, 4, -2, -4, -3, -1]
它给了我一个值列表,每个值只出现一次,但我希望它也以与原始列表相同的顺序打印它们。
Aset
没有顺序,因此在将列表转换为集合后,迭代元素时产生的顺序是实现细节。
您可以使用OrderedDict
来获得一些带有订单的设置行为:
>>> from collections import OrderedDict
>>> a = [2, -4, -2, 4, -3, -1, 3, 4, 2, 2]
>>> x = OrderedDict.fromkeys(a)
>>> list(x)
[2, -4, -2, 4, -3, -1, 3]
这是一种更快(虽然不太紧凑)的方法,它基本上迭代原始列表中的元素,检查它们是否还在set
您要添加的元素中。可能会有一些细微的变化可以进一步加快我的方法:
def _order(orig):
ordset = set()
for x in orig:
if x in ordset:
continue
ordset.add(x)
yield x
def unique(orig):
return list(_order(orig))
输出:
>>> unique(a)
[2, -4, -2, 4, -3, -1, 3]
基准测试:
戳的答案:
>>> import timeit
>>> setup = '''
a = [2, -4, -2, 4, -3, -1, 3, 4, 2, 2]
from collections import OrderedDict
def unique():
x = OrderedDict.fromkeys(a)
return list(x)
'''
>>> print (min(timeit.Timer('unique()', setup=setup).repeat(100, 1000)))
0.031305141204512665
上面的答案:
>>> import timeit
>>> setup = '''
a = [2, -4, -2, 4, -3, -1, 3, 4, 2, 2]
def _order(orig):
ordset = set()
for x in orig:
if x in ordset:
continue
ordset.add(x)
yield x
def unique(orig):
return list(_order(orig))
'''
>>> print (min(timeit.Timer('unique(a)', setup=setup).repeat(100, 1000)))
0.0031761333803501657
这种方法快了近 10 倍。对于这样的小列表,差异可以忽略不计,Poke 的回答很棒。但是,如果您碰巧对大量列表执行此操作(例如,长 10000 倍),则差异为 75 秒与 5 秒。