2

我有一个列表:

>>> 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}

有重复项并且它们以奇数顺序排列,关于如何在保持顺序和删除重复项的同时将其转换回列表的任何想法?

4

5 回答 5

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)

这里保留了顺序,只要每个重复项的第一次出现仍然在同一位置。

于 2013-10-14T22:32:37.950 回答
2
d = {e: i for i, e in enumerate (a) }
a = [x for x, _ in sorted(d.items (), key = lambda x: x [1] ) ]

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

于 2013-10-14T22:36:09.900 回答
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)对将从字典中取出,按列表中的位置排序,并截断为仅元素。

于 2013-10-14T22:34:04.507 回答
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]]

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

于 2013-10-14T22:58:54.627 回答
-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]
于 2013-10-14T22:49:04.720 回答