获取列表中唯一值的有趣代码
假设有一个列表 s = [2,2,2,3,3,3,4,4,4]
我看到有人用下面的代码来获取列表s中的唯一值:
unique_s = sorted(unique(s))
这里的唯一值是这样定义的:
def unique(seq):
# not order preserving
set = {}
map(set.__setitem__, seq, [])
return set.keys()
我只是好奇,这段代码和直接用 list(set(s))
有什么区别吗?这两种方法都能得到一个可变的对象,里面的值是一样的。
我在想,这段代码可能更快,因为它只循环了一次,而类型转换的情况下要循环两次?
2 个回答
1
对于一个已经排好序的序列,你可以使用itertools
的unique_justseen()方法来获取唯一的值,同时保持它们的顺序:
from itertools import groupby
from operator import itemgetter
print map(itemgetter(0), groupby([2,2,2,3,3,3,4,4,4]))
# -> [2, 3, 4]
如果你想在一个排好序的序列中直接去掉重复的项(只留下唯一的值):
def del_dups(sorted_seq):
prev = object()
pos = 0
for item in sorted_seq:
if item != prev:
prev = item
sorted_seq[pos] = item
pos += 1
del sorted_seq[pos:]
L = [2,2,2,3,3,3,4,4,4]
del_dups(L)
print L # -> [2, 3, 4]
3
你应该使用你所描述的代码:
list(set(s))
这个代码在所有从2.4(我记得没错的话)到3.3的Python版本上都能运行,简洁明了,并且使用了内置函数,容易理解。
这个叫做 unique
的函数似乎是为了在 set
不是内置函数的情况下也能工作,这在Python 2.3中是成立的。Python 2.3已经相当老了(发布于2003年)。而且,这个 unique
函数在Python 3.x系列中也有问题,因为在Python 3.x中, dict.keys
返回的是一个迭代器。