我如何检查一个列表是否有任何重复,并返回一个没有重复的新列表?


当前回答

如果你不关心顺序,就这样做:

def remove_duplicates(l):
    return list(set(l))

一个集合保证没有重复项。

其他回答

这里有很多答案使用set(..)(考虑到元素是可哈希的,这是快速的)或list(它的缺点是它会导致O(n2)算法。

我建议的函数是一个混合的函数:我们使用set(..)来表示可哈希的项,使用list(..)来表示不可哈希的项。此外,它被实现为一个生成器,例如,我们可以限制项目的数量,或做一些额外的过滤。

最后,我们还可以使用一个key参数来指定元素应以何种方式惟一。例如,如果我们想过滤一个字符串列表,这样输出中的每个字符串都有不同的长度,我们可以使用这个。

def uniq(iterable, key=lambda x: x):
    seens = set()
    seenl = []
    for item in iterable:
        k = key(item)
        try:
            seen = k in seens
        except TypeError:
            seen = k in seenl
        if not seen:
            yield item
            try:
                seens.add(k)
            except TypeError:
                seenl.append(k)

我们现在可以这样使用:

>>> list(uniq(["apple", "pear", "banana", "lemon"], len))
['apple', 'pear', 'banana']
>>> list(uniq(["apple", "pear", "lemon", "banana"], len))
['apple', 'pear', 'banana']
>>> list(uniq(["apple", "pear", {}, "lemon", [], "banana"], len))
['apple', 'pear', {}, 'banana']
>>> list(uniq(["apple", "pear", {}, "lemon", [], "banana"]))
['apple', 'pear', {}, 'lemon', [], 'banana']
>>> list(uniq(["apple", "pear", {}, "lemon", {}, "banana"]))
['apple', 'pear', {}, 'lemon', 'banana']

因此,它是一个唯一性过滤器,可以在任何可迭代对象上工作并过滤出唯一性对象,而不管这些唯一性对象是否可哈希。

它做了一个假设:如果一个对象是可哈希的,而另一个对象不是,这两个对象永远不相等。严格地说,这是可能发生的,尽管它是非常罕见的。

你也可以这样做:

>>> t = [1, 2, 3, 3, 2, 4, 5, 6]
>>> s = [x for i, x in enumerate(t) if i == t.index(x)]
>>> s
[1, 2, 3, 4, 5, 6]

上述工作的原因是index方法只返回元素的第一个索引。重复元素具有更高的下标。参考此处:

列表。索引(x[, start[, end]]) 的列表中返回从零开始的索引 如果没有,则引发ValueError异常 这样的项目。

如果你不关心顺序,想要一些不同于上面建议的python方式(也就是说,它可以在面试中使用),那么:

def remove_dup(arr):
    size = len(arr)
    j = 0    # To store index of next unique element
    for i in range(0, size-1):
        # If current element is not equal
        # to next element then store that
        # current element
        if(arr[i] != arr[i+1]):
            arr[j] = arr[i]
            j+=1

    arr[j] = arr[size-1] # Store the last element as whether it is unique or repeated, it hasn't stored previously

    return arr[0:j+1]

if __name__ == '__main__':
    arr = [10, 10, 1, 1, 1, 3, 3, 4, 5, 6, 7, 8, 8, 9]
    print(remove_dup(sorted(arr)))

时间复杂度:O(n)

辅助空间:O(n)

参考:http://www.geeksforgeeks.org/remove-duplicates-sorted-array/

如果你想保持顺序,不使用任何外部模块,这里有一个简单的方法:

>>> t = [1, 9, 2, 3, 4, 5, 3, 6, 7, 5, 8, 9]
>>> list(dict.fromkeys(t))
[1, 9, 2, 3, 4, 5, 6, 7, 8]

注意:这种方法保留了出现的顺序,因此,如上所示,9将在1之后,因为它是第一次出现。然而,这和你做的结果是一样的

from collections import OrderedDict
ulist=list(OrderedDict.fromkeys(l))

但它更短,跑得更快。

这是因为每次fromkeys函数尝试创建一个新键时,如果值已经存在,它就会简单地覆盖它。然而,这不会影响字典,因为fromkeys创建的字典中所有键的值都为None,因此有效地消除了所有重复的值。

可以使用Python set或dict.fromkeys()方法删除重复项。 dict.fromkeys()方法将一个列表转换为一个字典。字典不能包含重复的值,因此dict.fromkeys()将返回只有唯一值的字典。 集,像字典一样,不能包含重复的值。如果将列表转换为集合,则删除所有重复项。

方法一:幼稚法

mylist = [5, 10, 15, 20, 3, 15, 25, 20, 30, 10, 100]

uniques = []

for i in mylist:

    if i not in uniques:

       uniques.append(i)

print(uniques)

方法二:使用set()

mylist = [5, 10, 15, 20, 3, 15, 25, 20, 30, 10, 100]

myset = set(mylist)

print(list(myset))