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


当前回答

这里有一个例子,返回没有重复的列表,保持顺序。不需要任何外部导入。

def GetListWithoutRepetitions(loInput):
    # return list, consisting of elements of list/tuple loInput, without repetitions.
    # Example: GetListWithoutRepetitions([None,None,1,1,2,2,3,3,3])
    # Returns: [None, 1, 2, 3]

    if loInput==[]:
        return []

    loOutput = []

    if loInput[0] is None:
        oGroupElement=1
    else: # loInput[0]<>None
        oGroupElement=None

    for oElement in loInput:
        if oElement<>oGroupElement:
            loOutput.append(oElement)
            oGroupElement = oElement
    return loOutput

其他回答

另一种做法:

>>> seq = [1,2,3,'a', 'a', 1,2]
>> dict.fromkeys(seq).keys()
['a', 1, 2, 3]

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

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

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

下面的代码是简单的删除重复列表

def remove_duplicates(x):
    a = []
    for i in x:
        if i not in a:
            a.append(i)
    return a

print remove_duplicates([1,2,2,3,3,4])

它返回[1,2,3,4]

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']
]

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

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

>>> 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,因此有效地消除了所有重复的值。