Python 删除列表中的重复项

Python 删除列表中的重复项,python,list,Python,List,可能的重复项: 我想知道是否有一个函数可以执行以下操作: 将列表作为参数: list = [ 3 , 5 , 6 , 4 , 6 , 2 , 7 , 6 , 5 , 3 ] 并删除列表中的所有重复,以获得: list = [ 3 , 5 , 6 , 4 , 2 , 7 ] 我知道你可以把它转换成字典,利用字典不能重复的事实,但我想知道是否有更好的方法 谢谢列表(set(list))工作正常 有关实现此目的的三种方法,请参见。以下内容是从该站点复制的。用变量名(“列表”)替换示例“myli

可能的重复项:

我想知道是否有一个函数可以执行以下操作:

将列表作为参数:

list = [ 3 , 5 , 6 , 4 , 6 , 2 , 7 , 6 , 5 , 3 ]
并删除列表中的所有重复,以获得:

list = [ 3 , 5 , 6 , 4 , 2 , 7 ]
我知道你可以把它转换成字典,利用字典不能重复的事实,但我想知道是否有更好的方法

谢谢

列表(set(list))
工作正常

有关实现此目的的三种方法,请参见。以下内容是从该站点复制的。用变量名(“列表”)替换示例“mylist”

第一个示例:如果您不介意对列表重新排序,请对其进行排序,然后从列表末尾开始扫描,同时删除重复项:

if mylist:
    mylist.sort()
    last = mylist[-1]
    for i in range(len(mylist)-2, -1, -1):
        if last == mylist[i]:
            del mylist[i]
        else:
            last = mylist[i]
第二个示例:如果列表中的所有元素都可用作字典键(即它们都是可哈希的),则这通常更快:

d = {}
for x in mylist:
    d[x] = 1
mylist = list(d.keys())
第三个示例:在Python 2.5及更高版本中:

mylist = list(set(mylist))

首先,不要将其命名为list,因为它会隐藏内置类型列表。说,
myu列表

为了解决您的问题,我经常看到的方法是
list(set(my_list))

set是一个无序的容器,它只包含唯一的元素,并且(我认为)O(1)插入和检查成员资格

list(set(l))
不会保留顺序。如果您想维持订单,请执行以下操作:

s = set()
result = []
for item in l:
    if item not in s:
        s.add(item)
        result.append(item)

print result

这将在O(n)中运行,其中n是原始列表的长度。

一个集合将比一个O复杂度的字典术语更好。但这两种方法都会使您放松排序(除非您使用有序字典,否则会再次增加复杂性)

正如其他海报所说,set解决方案并不难:

l = [ 3 , 5 , 6 , 4 , 6 , 2 , 7 , 6 , 5 , 3 ]
list(set(l))
保持订单的一种方法是:

def uniques(l):
    seen = set()

    for i in l:
        if i not in seen:
            seen.add(i)
            yield i
或者,以可读性较差的方式:

def uniques(l):
    seen = set()
    return (seen.add(i) or i for i in l if i not in seen)
然后您可以这样使用它:

l = [ 3 , 5 , 6 , 4 , 6 , 2 , 7 , 6 , 5 , 3 ]
list(uniques(l))
>>> [3, 5, 6, 4, 2, 7]

尽管您说您不一定要使用
dict
,但我认为
orderedict
在这里是一个干净的解决方案

from collections import OrderedDict

l = [3 ,5 ,6 ,4 ,6 ,2 ,7 ,6 ,5 ,3]
OrderedDict.fromkeys(l).keys()
# [3, 5, 6, 4, 2, 7]

请注意,这保留了原始顺序。

在撰写此答案时,唯一保持顺序的解决方案是OrderedDict解决方案,以及Dave稍微详细一点的解决方案

这是我们在迭代时滥用副作用的另一种方式,它也比OrderedDict解决方案更详细:

def uniques(iterable):
    seen = set()
    sideeffect = lambda _: True
    return [x for x in iterable 
            if (not x in seen) and sideeffect(seen.add(x))]

下面是我自己收集的一些方便的Python工具中的一个片段——它使用了ninjagecko在回答中使用的“滥用副作用”方法。处理不可散列的值以及返回与传入的相同类型的序列也需要付出很大的努力:

def unique(seq, keepstr=True):
    """Function to keep only the unique values supplied in a given 
       sequence, preserving original order."""

    # determine what type of return sequence to construct
    if isinstance(seq, (list,tuple)):
        returnType = type(seq)
    elif isinstance(seq, basestring):
        returnType = (list, type(seq)('').join)[bool(keepstr)] 
    else:
        # - generators and their ilk should just return a list
        returnType = list

    try:
        seen = set()
        return returnType(item for item in seq if not (item in seen or seen.add(item)))
    except TypeError:
        # sequence items are not of a hashable type, can't use a set for uniqueness
        seen = []
        return returnType(item for item in seq if not (item in seen or seen.append(item)))
以下是各种调用,具有各种类型的序列/迭代器/生成器:

from itertools import chain
print unique("ABC")
print unique(list("ABABBAC"))
print unique(range(10))
print unique(chain(reversed(range(5)), range(7)))
print unique(chain(reversed(xrange(5)), xrange(7)))
print unique(i for i in chain(reversed(xrange(5)), xrange(7)) if i % 2)
印刷品:

ABC
['A', 'B', 'C']
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[4, 3, 2, 1, 0, 5, 6]
[4, 3, 2, 1, 0, 5, 6]
[3, 1, 5]

你关心元素的顺序吗?如果“好”的意思是“我不关心原始顺序”,那么是的。