Python:从列表中删除重复项,同时使用字典保留顺序

时间:2013-10-14 22:27:18

标签: python list dictionary

我有一个列表:

>>> a = big_list(30)
>>> a
[-14, -13, 10, 7, -10, 5, 3, 10, 8, -13, 14, -12, 6, 10, 8, 7, 4, -8, -10, -3, -6, 2, -6, 3, -3, 0, -13, -14, 2, -12]

我需要使用字典

从保留顺序中删除重复项

到目前为止,我使用此代码将a转换为字典

def only_once(a):
    i = iter(a)
    print dict(zip(i,i))
输出是:

>>> only_once(a)
{2: -12, 3: 10, 4: -8, 6: 10, 8: 7, 10: 7, 14: -12, -14: -13, -13: -14, -10: -3, -6: 3, -3: 0}

有重复项,它们按照奇怪的顺序排列,有关如何将其转换回列表同时保持顺序并删除重复项的任何想法?

5 个答案:

答案 0 :(得分:3)

使用OrderedDict:

x = [-14, -13, 10, 7, -10, 5, 3, 10, 8, -13, 14, -12, 6, 10, 8, 7, 4, -8, -10, -3, -6, 2, -6, 3, -3, 0, -13, -14, 2, -12]
from collections import OrderedDict
d = OrderedDict.fromkeys(x)
x = list(d)

此处保留订单,因为每个副本的第一次出现仍然在同一位置。

答案 1 :(得分:2)

d = {e: i for i, e in enumerate (a) }
a = [x for x, _ in sorted(d.items (), key = lambda x: x [1] ) ]

当一个项目在原始列表中多次出现时,它的最后一次出现将被保留。

答案 2 :(得分:1)

字典不存储订单。要使用纯字典执行您要执行的操作,您还需要将该位置存储在字典的列表中。

def only_once(a):
    d = dict((b,a) for (a,b) in enumerate(a))
    new = d.items()
    return [x[0] for x in sorted(new, key=lambda a: a[1])]

这将创建一个字典,其中键是元素,值是列表中的位置,这意味着元素的第一次出现将被稍后的事件覆盖(调用reversed()来切换此行为) 。然后,(key,value)对将从字典中拉出,按列表中的位置排序,并截断为仅元素。

答案 3 :(得分:0)

由于您没有指定 字典需要如何使用,并且没有迹象表明代码需要高效,我想有很多可能的答案。例如使用指数

first_index = {v: len(a) - 1 - i for i, v in enumerate(reversed(a))}
print [v for i, v  in enumerate(a) if i == first_index[v]]

(我假设您要删除列表中稍后出现的重复项,同时保留第一次出现的内容。)

答案 4 :(得分:-1)

创建一组您要保留的项目,并丢弃您已保留的项目:

>>> a = [-14, -13, 10, 7, -10, 5, 3, 10, 8, -13, 14, -12, 6, 10, 8, 7, 4, -8, -10, -3, -6, 2, -6, 3, -3, 0, -13, -14, 2, -12]
>>> s = set()
>>> [ item for item in a if item not in s and s.add(item) == None]
[-14, -13, 10, 7, -10, 5, 3, 8, 14, -12, 6, 4, -8, -3, -6, 2, 0]

可以使用字典而不是set,但它非常人为:

>>> d = {}
>>> [ item for item in a if item not in d and d.update({item:None}) == None]
[-14, -13, 10, 7, -10, 5, 3, 8, 14, -12, 6, 4, -8, -3, -6, 2, 0]