获取列表中唯一值的有趣代码

0 投票
2 回答
1243 浏览
提问于 2025-04-17 11:13

假设有一个列表 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 返回的是一个迭代器。

撰写回答