如何使用集合保持列表的顺序?

6 投票
3 回答
14893 浏览
提问于 2025-04-16 03:16
In [1]: l1 = ['a',2,3,0,9.0,0,2,6,'b','a']

In [2]: l2 = list(set(l1))

In [3]: l2
Out[3]: ['a', 0, 2, 3, 6, 9.0, 'b']

在这里,你可以看到列表 l2 的顺序和原来的 l1 不一样。我需要从我的列表中去掉重复的元素,但又不想改变列表中元素的顺序。

3 个回答

0

这是我随便想出来的(用字典来做):

l1 = ['a',2,3,0,9.0,0,2,6,'b','a']
l2 = []
s = {}
for i in l1:
    if not i in s:
        l2.append(i)
        s[i] = None

# l2 contains ['a', 2, 3, 0, 9.0, 6, 'b', 'a']

补充:用集合(也是随便想的):

l1 = ['a',2,3,0,9.0,0,2,6,'b','a']
l2 = []
s = set()
for i in l1:
   if not i in s:
       l2.append(i)
       s.add(i)
6

你可以通过定义一个这样的函数来解决这个问题:

def dedupe(items):
    seen = set()
    for item in items:
        if item not in seen:
            yield item
            seen.add(item)

使用这个函数的方法是:

>>> l1 = ['a',2,3,0,9.0,0,2,6,'b','a']
>>> l2 = list(dedupe(l1))
>>> l2
['a', 2, 3, 0, 9.0, 6, 'b']
15

如果你不太在意效率的话,这个操作的复杂度是 O(n*m),也就是说处理的时间会随着两个列表的元素数量的乘积而增加。

>>> sorted(set(l1), key=l1.index)
['a', 2, 3, 0, 9.0, 6, 'b']

使用一个中间的字典会更复杂一些,但它的复杂度是 O(n+m*logm),这意味着处理的时间会随着第一个列表的元素数量和第二个列表中独特元素的数量而变化。

这里的 n 是 l1 中的元素数量,而 m 是 l1 中独特元素的数量。

>>> l1 = ['a',2,3,0,9.0,0,2,6,'b','a']
>>> d1=dict((k,v) for v,k in enumerate(reversed(l1)))
>>> sorted(d1, key=d1.get, reverse=True)
['a', 2, 3, 0, 9.0, 6, 'b']

在 Python3.1 中,你可以使用 OrderedDict,这样操作起来就简单多了。

>>> l1 = ['a',2,3,0,9.0,0,2,6,'b','a'] 
>>> list(OrderedDict.fromkeys(l1))
['a', 2, 3, 0, 9.0, 6, 'b']

撰写回答