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


当前回答

它需要安装一个第三方模块,但包iteration_utilities包含一个unique_everseen1函数,可以删除所有重复的同时保留顺序:

>>> from iteration_utilities import unique_everseen

>>> list(unique_everseen(['a', 'b', 'c', 'd'] + ['a', 'c', 'd']))
['a', 'b', 'c', 'd']

如果你想避免列表添加操作的开销,你可以使用itertools。链:

>>> from itertools import chain
>>> list(unique_everseen(chain(['a', 'b', 'c', 'd'], ['a', 'c', 'd'])))
['a', 'b', 'c', 'd']

unique_everseen也适用于列表中有不可哈希项(例如列表)的情况:

>>> from iteration_utilities import unique_everseen
>>> list(unique_everseen([['a'], ['b'], 'c', 'd'] + ['a', 'c', 'd']))
[['a'], ['b'], 'c', 'd', 'a']

然而,这将比项目是可哈希的(多)慢。


1披露:我是iteration_utilities-library的作者。

其他回答

一个更好的方法是,

import pandas as pd

myList = [1, 2, 3, 1, 2, 5, 6, 7, 8]
cleanList = pd.Series(myList).drop_duplicates().tolist()
print(cleanList)

#> [1, 2, 3, 5, 6, 7, 8]

秩序得以维持。

这里有很多答案使用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']

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

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

我用纯python函数做到了这一点。当您的项目值是JSON时,这是有效的。

[i for n, i in enumerate(items) if i not in items[n + 1 :]]
Test = [1,8,2,7,3,4,5,1,2,3,6]
Test.sort()
i=1
while i< len(Test):
  if Test[i] == Test[i-1]:
    Test.remove(Test[i])
  i= i+1
print(Test)

Python的魔力内置类型

在python中,仅通过python的内置类型就可以很容易地处理这样复杂的情况。

让我告诉你怎么做!

方法一:一般情况

方法(1行代码)删除重复的元素在列表中仍然保持排序顺序

line = [1, 2, 3, 1, 2, 5, 6, 7, 8]
new_line = sorted(set(line), key=line.index) # remove duplicated element
print(new_line)

你会得到结果的

[1, 2, 3, 5, 6, 7, 8]

方法二:特殊情况

TypeError: unhashable type: 'list'

处理不可哈希的特殊情况(3行代码)

line=[['16.4966155686595', '-27.59776154691', '52.3786295521147']
,['16.4966155686595', '-27.59776154691', '52.3786295521147']
,['17.6508629295574', '-27.143305738671', '47.534955022564']
,['17.6508629295574', '-27.143305738671', '47.534955022564']
,['18.8051102904552', '-26.688849930432', '42.6912804930134']
,['18.8051102904552', '-26.688849930432', '42.6912804930134']
,['19.5504702331098', '-26.205884452727', '37.7709192714727']
,['19.5504702331098', '-26.205884452727', '37.7709192714727']
,['20.2929416861422', '-25.722717575124', '32.8500163147157']
,['20.2929416861422', '-25.722717575124', '32.8500163147157']]

tuple_line = [tuple(pt) for pt in line] # convert list of list into list of tuple
tuple_new_line = sorted(set(tuple_line),key=tuple_line.index) # remove duplicated element
new_line = [list(t) for t in tuple_new_line] # convert list of tuple into list of list

print (new_line)

你会得到这样的结果:

[
  ['16.4966155686595', '-27.59776154691', '52.3786295521147'], 
  ['17.6508629295574', '-27.143305738671', '47.534955022564'], 
  ['18.8051102904552', '-26.688849930432', '42.6912804930134'], 
  ['19.5504702331098', '-26.205884452727', '37.7709192714727'], 
  ['20.2929416861422', '-25.722717575124', '32.8500163147157']
]

因为元组是可哈希的,你可以很容易地在列表和元组之间转换数据