Python 2.7 中的有序集合

12 投票
8 回答
22972 浏览
提问于 2025-04-16 18:44

我有一个列表,想要去掉里面重复的项目。我使用的是python 2.7.1,所以可以直接用set()这个函数。不过,这样会改变我列表的顺序,而在我的情况下,这是不可接受的。

下面是我写的一个函数,可以实现这个功能。不过我在想有没有更好或更快的方法。同时,如果有人能给点建议,我会很感激。

    def ordered_set(list_):

        newlist = []
        lastitem = None
        for item in list_:

            if item != lastitem:
                newlist.append(item)
                lastitem = item

        return newlist

这个函数假设列表里的项目都不会是None,而且项目是有顺序的(比如说['a', 'a', 'a', 'b', 'b', 'c', 'd'])。

这个函数的输出是['a', 'a', 'a', 'b', 'b', 'c', 'd'],而它想要的结果是['a', 'b', 'c', 'd']

8 个回答

7

假设输入的序列是无序的,这里有一个时间和空间复杂度都是O(N)的解决方案。这个方法可以去掉重复的项,同时保持唯一项在输入序列中出现的相对顺序不变。

>>> def remove_dups_stable(s):
...   seen = set()
...   for i in s:
...     if i not in seen:
...       yield i
...       seen.add(i)

>>> list(remove_dups_stable(['q', 'w', 'e', 'r', 'q', 'w', 'y', 'u', 'i', 't', 'e', 'p', 't', 'y', 'e']))
['q', 'w', 'e', 'r', 'y', 'u', 'i', 't', 'p']
12

另一种非常快速的方法是使用集合(set):

def remove_duplicates(lst):
    dset = set()
    # relies on the fact that dset.add() always returns None.
    return [item for item in lst
            if item not in dset and not dset.add(item)] 
9

使用一个有序字典(OrderedDict):

from collections import OrderedDict

l = ['a', 'a', 'a', 'b', 'b', 'c', 'd']
d = OrderedDict()

for x in l:
    d[x] = True

# prints a b c d
for x in d:
    print x,
print

撰写回答