删除列表中的重复项

时间:2011-11-01 00:45:24

标签: python algorithm list duplicates intersection

我几乎需要编写一个程序来检查列表是否有任何重复项,如果是,它会删除它们并返回一个新列表,其中包含未复制/删除的项目。这就是我所拥有的,但说实话,我不知道该怎么做。

def remove_duplicates():
    t = ['a', 'b', 'c', 'd']
    t2 = ['a', 'c', 'd']
    for t in t2:
        t.append(t.remove())
    return t

55 个答案:

答案 0 :(得分:1339)

获取唯一项目集合的常用方法是使用set。集合是不同对象的无序集合。要从任何可迭代创建集合,您只需将其传递给内置set()函数即可。如果您稍后再次需要真实列表,则可以类似地将该集合传递给list()函数。

以下示例应涵盖您要执行的操作:

>>> t = [1, 2, 3, 1, 2, 5, 6, 7, 8]
>>> t
[1, 2, 3, 1, 2, 5, 6, 7, 8]
>>> list(set(t))
[1, 2, 3, 5, 6, 7, 8]
>>> s = [1, 2, 3]
>>> list(set(t) - set(s))
[8, 5, 6, 7]

从示例结果中可以看出,未保留原始订单。如上所述,集合本身是无序集合,因此订单丢失。将一个集转换回列表时,会创建一个任意顺序。

如果订单对您很重要,那么您将不得不使用不同的机制。一个非常常见的解决方案是依靠OrderedDict在插入过程中保持键的顺序:

>>> from collections import OrderedDict
>>> list(OrderedDict.fromkeys(t))
[1, 2, 3, 5, 6, 7, 8]

请注意,这会产生首先创建字典,然后从中创建列表的开销。因此,如果您实际上不需要保留订单,那么最好使用一套。查看this question以获取更多详细信息以及删除重复项时保留订单的其他方法。


最后请注意,setOrderedDict解决方案都要求您的商品 hashable 。这通常意味着它们必须是不可变的。如果你必须处理不可清除的项目(例如列表对象),那么你将不得不使用一种缓慢的方法,在这种方法中你基本上必须将每个项目与嵌套循环中的每个其他项目进行比较。

答案 1 :(得分:366)

在Python 2.7 中,从迭代中删除重复项同时保持原始顺序的新方法是:

>>> from collections import OrderedDict
>>> list(OrderedDict.fromkeys('abracadabra'))
['a', 'b', 'r', 'c', 'd']

在Python 3.5 中,OrderedDict有一个C实现。我的时间表明,现在这是Python 3.5的各种方法中最快和最短的。

在Python 3.6 中,常规字典变得有序且紧凑。 (此功能适用于CPython和PyPy,但在其他实现中可能不存在)。这为我们提供了一种新的最快的扣除方式,同时保留了订单:

>>> list(dict.fromkeys('abracadabra'))
['a', 'b', 'r', 'c', 'd']

在Python 3.7 中,保证常规字典在所有实现中都有序。 因此,最短和最快的解决方案是:

>>> list(dict.fromkeys('abracadabra'))
['a', 'b', 'r', 'c', 'd']

答案 2 :(得分:175)

这是一个单行:list(set(source_list))会做到这一点。

set是不可能有重复的东西。

更新:订单保留方法有两行:

from collections import OrderedDict
OrderedDict((x, True) for x in source_list).keys()

这里我们使用OrderedDict记住键的插入顺序的事实,并且在更新特定键的值时不会更改它。我们插入True作为值,但我们可以插入任何内容,只是不使用值。 (setdict的工作方式非常相似,但忽略了值。)

答案 3 :(得分:81)

>>> t = [1, 2, 3, 1, 2, 5, 6, 7, 8]
>>> t
[1, 2, 3, 1, 2, 5, 6, 7, 8]
>>> s = []
>>> for i in t:
       if i not in s:
          s.append(i)
>>> s
[1, 2, 3, 5, 6, 7, 8]

答案 4 :(得分:73)

如果您不关心订单,请执行以下操作:

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

保证set没有重复项。

答案 5 :(得分:33)

创建一个新列表,保留L

中重复项的第一个元素的顺序

newlist=[ii for n,ii in enumerate(L) if ii not in L[:n]]

例如if L=[1, 2, 2, 3, 4, 2, 4, 3, 5],然后newlist将为[1,2,3,4,5]

这会在添加之前检查先前未在列表中出现的每个新元素。 它也不需要进口。

答案 6 :(得分:20)

一位同事已将接受的答案作为其代码的一部分发送给我,以便我今天进行代码审查。 虽然我当然钦佩有问题的答案的优雅,但我对表现并不满意。 我尝试过这个解决方案(我使用 set 来减少查找时间)

def ordered_set(in_list):
    out_list = []
    added = set()
    for val in in_list:
        if not val in added:
            out_list.append(val)
            added.add(val)
    return out_list

为了比较效率,我使用了100个整数的随机样本--62个是唯一的

from random import randint
x = [randint(0,100) for _ in xrange(100)]

In [131]: len(set(x))
Out[131]: 62

以下是测量结果

In [129]: %timeit list(OrderedDict.fromkeys(x))
10000 loops, best of 3: 86.4 us per loop

In [130]: %timeit ordered_set(x)
100000 loops, best of 3: 15.1 us per loop

那么,如果从解决方案中移除了set,​​会发生什么?

def ordered_set(inlist):
    out_list = []
    for val in inlist:
        if not val in out_list:
            out_list.append(val)
    return out_list

结果没有 OrderedDict 那么糟糕,但仍然是原始解决方案的3倍以上

In [136]: %timeit ordered_set(x)
10000 loops, best of 3: 52.6 us per loop

答案 7 :(得分:19)

另一种做法:

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

答案 8 :(得分:18)

还有使用Pandas和Numpy的解决方案。它们都返回numpy数组,因此如果需要列表,则必须使用函数.tolist()

t=['a','a','b','b','b','c','c','c']
t2= ['c','c','b','b','b','a','a','a']

熊猫解决方案

使用Pandas功能unique()

import pandas as pd
pd.unique(t).tolist()
>>>['a','b','c']
pd.unique(t2).tolist()
>>>['c','b','a']

Numpy解决方案

使用numpy函数unique()

import numpy as np
np.unique(t).tolist()
>>>['a','b','c']
np.unique(t2).tolist()
>>>['a','b','c']

请注意,numpy.unique()还会对值进行排序。因此列表t2被返回排序。如果您希望保留订单,请使用this answer

_, idx = np.unique(t2, return_index=True)
t2[np.sort(idx)].tolist()
>>>['c','b','a']

与其他解决方案相比,解决方案并不那么优雅,但是,与pandas.unique()相比,numpy.unique()还允许您检查嵌套数组在一个选定轴上是否唯一。

答案 9 :(得分:15)

简单易行:

myList = [1, 2, 3, 1, 2, 5, 6, 7, 8]
cleanlist = []
[cleanlist.append(x) for x in myList if x not in cleanlist]

输出:

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

答案 10 :(得分:10)

我的名单中有一个词典,所以我无法使用上述方法。我收到了错误:

TypeError: unhashable type:

因此,如果您关心订单和/或某些商品不可取消。然后你可能会觉得这很有用:

def make_unique(original_list):
    unique_list = []
    [unique_list.append(obj) for obj in original_list if obj not in unique_list]
    return unique_list

有些人可能会认为列表理解具有副作用并不是一个好的解决方案。这是另一种选择:

def make_unique(original_list):
    unique_list = []
    map(lambda x: unique_list.append(x) if (x not in unique_list) else False, original_list)
    return unique_list

答案 11 :(得分:10)

很晚才回答。如果您不在乎列表顺序,则可以使用*arg扩展来删除重复项,即:

l = [*{*l}]

Demo

答案 12 :(得分:6)

到目前为止,我在这里看到的所有顺序保留方法都使用了天真的比较(最好是O(n ^ 2)时间复杂度)或者是重量级set / list + key组合仅限于可输入的输入。这是一个与哈希无关的O(nlogn)解决方案:

更新添加了# from functools import reduce <-- add this import on Python 3 def uniq(iterable, key=lambda x: x): """ Remove duplicates from an iterable. Preserves order. :type iterable: Iterable[Ord => A] :param iterable: an iterable of objects of any orderable type :type key: Callable[A] -> (Ord => B) :param key: optional argument; by default an item (A) is discarded if another item (B), such that A == B, has already been encountered and taken. If you provide a key, this condition changes to key(A) == key(B); the callable must return orderable objects. """ # Enumerate the list to restore order lately; reduce the sorted list; restore order def append_unique(acc, item): return acc if key(acc[-1][1]) == key(item[1]) else acc.append(item) or acc srt_enum = sorted(enumerate(iterable), key=lambda item: key(item[1])) return [item[1] for item in sorted(reduce(append_unique, srt_enum, [srt_enum[0]]))] 参数,文档和Python 3兼容性。

public boolean changePassword(...) {
    if(not correct) {
        return false;
    }
    return true;
}

答案 13 :(得分:6)

你也可以这样做:

>>> 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方法只返回元素的第一个索引。重复元素具有更高的索引。请参阅here

  

list.index(x [,start [,end]])
  在列表中返回从零开始的索引   值为x的第一个项目。如果没有,则引发ValueError   这样的项目。

答案 14 :(得分:6)

尝试使用套装:

import sets
t = sets.Set(['a', 'b', 'c', 'd'])
t1 = sets.Set(['a', 'b', 'c'])

print t | t1
print t - t1

答案 15 :(得分:5)

通过订购保留减少变量:

假设我们有列表:

l = [5, 6, 6, 1, 1, 2, 2, 3, 4]

减少变量(效率不高):

>>> reduce(lambda r, v: v in r and r or r + [v], l, [])
[5, 6, 1, 2, 3, 4]

快5倍但更复杂

>>> reduce(lambda r, v: v in r[1] and r or (r[0].append(v) or r[1].add(v)) or r, l, ([], set()))[0]
[5, 6, 1, 2, 3, 4]

说明:

default = (list(), set())
# user list to keep order
# use set to make lookup faster

def reducer(result, item):
    if item not in result[1]:
        result[0].append(item)
        result[1].add(item)
    return result

reduce(reducer, l, default)[0]

答案 16 :(得分:5)

您可以使用以下功能:

def rem_dupes(dup_list): 
    yooneeks = [] 
    for elem in dup_list: 
        if elem not in yooneeks: 
            yooneeks.append(elem) 
    return yooneeks

示例

my_list = ['this','is','a','list','with','dupicates','in', 'the', 'list']

用法:

rem_dupes(my_list)

['this','is','a','list','with','dupicates','in','the']

答案 17 :(得分:5)

不使用set

data=[1, 2, 3, 1, 2, 5, 6, 7, 8]
uni_data=[]
for dat in data:
    if dat not in uni_data:
        uni_data.append(dat)

print(uni_data) 

答案 18 :(得分:5)

在此答案中,将分为两个部分:两个独特的解决方案,以及特定解决方案的速度图。

删除重复项

大多数这些答案仅删除了可哈希的重复项,但是这个问题并不意味着它不仅仅需要 hashable 项,这意味着我会提供一些不需要 hashable 项目的解决方案。

collections.Counter 是标准库中一个功能强大的工具,可能对此非常理想。只有另一种解决方案甚至包含Counter。但是,该解决方案也仅限于 hashable 键。

为了在Counter中允许不可散列的键,我做了一个Container类,它将尝试获取对象的默认散列函数,但是如果失败,它将尝试其标识函数。它还定义了 eq hash 方法。这应该足以允许我们的解决方案中的 unhashable 项目。不可哈希对象将被视为可哈希对象。但是,此哈希函数对不可哈希对象使用标识,这意味着两个不可哈希的相等对象将不起作用。我建议您重写此方法,然后将其更改为使用均等可变类型的哈希(例如,如果hash(tuple(my_list))是列表,则使用my_list)。

我也提出了两种解决方案。另一个解决方案是使用OrderedDict和Counter的子类(称为“ OrderedCounter”)来保持商品的顺序。现在,这里是功能:

from collections import OrderedDict, Counter

class Container:
    def __init__(self, obj):
        self.obj = obj
    def __eq__(self, obj):
        return self.obj == obj
    def __hash__(self):
        try:
            return hash(self.obj)
        except:
            return id(self.obj)

class OrderedCounter(Counter, OrderedDict):
     'Counter that remembers the order elements are first encountered'

     def __repr__(self):
         return '%s(%r)' % (self.__class__.__name__, OrderedDict(self))

     def __reduce__(self):
         return self.__class__, (OrderedDict(self),)

def remd(sequence):
    cnt = Counter()
    for x in sequence:
        cnt[Container(x)] += 1
    return [item.obj for item in cnt]

def oremd(sequence):
    cnt = OrderedCounter()
    for x in sequence:
        cnt[Container(x)] += 1
    return [item.obj for item in cnt]

remd是非有序排序,而oremd是有序排序。您可以清楚地分辨出哪一个速度更快,但无论如何我都会解释。无序排序略快。由于不需要排序,因此可以保留较少的数据。

现在,我还想显示每个答案的速度比较。所以,我现在要做。

哪个功能最快?

为了删除重复项,我从几个答案中收集了10个函数。我计算了每个函数的速度,并使用 matplotlib.pyplot 将其放入图表中。

我将其分为三轮。可哈希对象是可以被哈希处理的任何对象,不可哈希对象是不能被哈希处理的任何对象。有序序列是保留顺序的序列,无序序列不保留顺序。现在,这里还有一些术语:

无序可散列适用于删除重复项的任何方法,这些方法不一定必须保持顺序。它不必为无法哈希​​的文件工作,但是可以。

Ordered Hashable 适用于将列表中项目的顺序保持不变的任何方法,但它不一定适用于不可哈希的对象,但可以。

订购不可散列是保留列表中项目顺序并适用于不可散列的任何方法。

在y轴上是花费的秒数。

在x轴上是应用该功能的编号。

我们通过以下理解为无序哈希和有序哈希生成序列:[list(range(x)) + list(range(x)) for x in range(0, 1000, 10)]

对于有序的不可哈希值:[[list(range(y)) + list(range(y)) for y in range(x)] for x in range(0, 1000, 10)]

请注意,该范围内有一个“台阶”,因为没有它,这将花费10倍的时间。另外,由于我个人的观点,我认为它看起来似乎更容易阅读。

还请注意,图例上的键是我试图猜测为功能最重要的部分。至于什么功能最差或最好?该图说明一切。

解决了之后,下面是图表。

无序哈希表

enter image description here (放大) enter image description here

订购的哈希表

enter image description here (放大) enter image description here

订购的不可散列

enter image description here (放大) enter image description here

答案 19 :(得分:5)

从列表中删除重复项的最佳方法是使用python中提供的 set()函数,再次将设置转换为列表

In [2]: some_list = ['a','a','v','v','v','c','c','d']
In [3]: list(set(some_list))
Out[3]: ['a', 'c', 'd', 'v']

答案 20 :(得分:4)

下面的代码很容易删除列表中的重复

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]

答案 21 :(得分:4)

还有一种更好的方法,

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]

,订单保持不变。

答案 22 :(得分:4)

如果您想保留订单,并且不使用任何外部模块,则可以通过以下简便方法进行操作:

>>> 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个。但是,这与您得到的结果相同

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

但是它更短,并且运行更快。

之所以有用,是因为每次fromkeys函数尝试创建一个新键时,如果该值已经存在,它将简单地覆盖它。但是,这根本不会影响字典,因为fromkeys创建了一个字典,其中所有键的值均为None,因此有效地消除了这种方式的所有重复项。

答案 23 :(得分:4)

这个人在没有太多麻烦的情况下关心订单(OrderdDict&amp; others)。可能不是最恐怖的方式,也不是最短的方式,但是诀窍是:

def remove_duplicates(list):
    ''' Removes duplicate items from a list '''
    singles_list = []
    for element in list:
        if element not in singles_list:
            singles_list.append(element)
    return singles_list

答案 24 :(得分:4)

还有许多其他答案表明采用不同的方法,但他们是所有批处理操作,其中一些会丢弃原始订单。这可能是好的,具体取决于你需要什么,但如果你想按照每个值的第一个实例的顺序迭代值,并且你想要一次性删除重复项,你可以使用这个发电机:

def uniqify(iterable):
    seen = set()
    for item in iterable:
        if item not in seen:
            seen.add(item)
            yield item

这将返回一个生成器/迭代器,因此您可以在任何可以使用迭代器的地方使用它。

for unique_item in uniqify([1, 2, 3, 4, 3, 2, 4, 5, 6, 7, 6, 8, 8]):
    print(unique_item, end=' ')

print()

输出:

1 2 3 4 5 6 7 8

如果你想要list,你可以这样做:

unique_list = list(uniqify([1, 2, 3, 4, 3, 2, 4, 5, 6, 7, 6, 8, 8]))

print(unique_list)

输出:

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

答案 25 :(得分:3)

使用 设置

a = [0,1,2,3,4,3,3,4]
a = list(set(a))
print a

使用 唯一

import numpy as np
a = [0,1,2,3,4,3,3,4]
a = np.unique(a).tolist()
print a

答案 26 :(得分:3)

这是最快的pythonic解决方案,与回复中列出的其他人合作。

使用短路评估的实现细节允许使用列表理解,这足够快。 visited.add(item)始终返回None作为结果,评估为False,因此or的右侧始终是此类表达式的结果。

自己计时

def deduplicate(sequence):
    visited = set()
    adder = visited.add  # get rid of qualification overhead
    out = [adder(item) or item for item in sequence if item not in visited]
    return out

答案 27 :(得分:3)

Python 3中非常简单的方法:

>>> n = [1, 2, 3, 4, 1, 1]
>>> n
[1, 2, 3, 4, 1, 1]
>>> m = sorted(list(set(n)))
>>> m
[1, 2, 3, 4]

答案 28 :(得分:2)

我认为转换为set是删除重复的最简单方法:

list1 = [1,2,1]
list1 = list(set(list1))
print list1

答案 29 :(得分:2)

这是一个示例,返回列表没有保留顺序的重复。不需要任何外部进口。

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

答案 30 :(得分:2)

我是用纯python函数完成的。当您的items值为JSON时,此方法有效。

[i for n, i in enumerate(items) if i not in items[n + 1 :]]

答案 31 :(得分:2)

Python内置类型的魔力

在python中,仅通过python的内置类型,即可轻松处理此类复杂情况。

让我告诉您如何做!

方法1:一般情况

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]

方法2:特殊情况

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

因为元组是可哈希的,并且您可以轻松地在列表和元组之间转换数据

答案 32 :(得分:2)

如果你想删除重复项(就地编辑而不是返回新列表)而不使用内置集,dict.keys,uniqify,counter

,请选中此项
>>> t = [1, 2, 3, 1, 2, 5, 6, 7, 8]
>>> for i in t:
...     if i in t[t.index(i)+1:]:
...         t.remove(i)
... 
>>> t
[3, 1, 2, 5, 6, 7, 8]

答案 33 :(得分:2)

很不幸。此处的大多数答案要么不保留顺序,要么太长。这是一个简单的订单保留答案。

<hr style=" border: 0;  height: 1px;  background: green;"/>

这将为您x删除重复项,但保留顺序。

答案 34 :(得分:2)

您可以使用set删除重复项:

mylist = list(set(mylist))

但是请注意,结果将是无序的。如果这是一个问题:

mylist.sort()

答案 35 :(得分:1)

我没有看到非散列值的答案,一个衬里,n log n,仅标准库,所以这是我的答案:

list(map(operator.itemgetter(0), itertools.groupby(sorted(items))))

或作为生成器函数:

def unique(items: Iterable[T]) -> Iterable[T]:
    """For unhashable items (can't use set to unique) with a partial order"""
    yield from map(operator.itemgetter(0), itertools.groupby(sorted(items)))

答案 36 :(得分:1)

def remove_duplicates(A):
   [A.pop(count) for count,elem in enumerate(A) if A.count(elem)!=1]
   return A

列表复制以删除重复项

答案 37 :(得分:1)

另一种解决方案可能如下。从列表中创建一个字典,其中item为key,索引为value,然后打印字典键。

    <!-- Spring -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>5.0.2.RELEASE</version>
    </dependency>
    <!--  -->
    <!-- Spring AOP -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>5.0.2.RELEASE</version>
    </dependency>
    <!-- AspectJ -->
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.8.13</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.8.13</version>
    </dependency>

答案 38 :(得分:1)

这里有很多答案,使用set(..)(快速给定元素是 hashable )或列表(其缺点是导致< em> O(n 2 )算法。

我建议的功能是混合功能:我们使用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']

因此,它是一个uniqeness过滤器,可以处理任何可迭代的过滤器并过滤掉唯一身份,无论它们是否可以清洗。

它做了一个假设:如果一个对象是可清洗的,而另一个对象是不可用的,那么这两个对象永远不会相等。严格来说,这可能会发生,尽管这种情况非常罕见。

答案 39 :(得分:1)

如果你不关心秩序,想要与上面建议的pythonic方法不同的东西(也就是说,它可以在面试中使用)那么:

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/

答案 40 :(得分:1)

您只需使用套装即可完成此操作。

Step1:获取列表的不同元素
Step2 获取列表的常用元素
Step3 合并它们

In [1]: a = ["apples", "bananas", "cucumbers"]

In [2]: b = ["pears", "apples", "watermelons"]

In [3]: set(a).symmetric_difference(b).union(set(a).intersection(b))
Out[3]: {'apples', 'bananas', 'cucumbers', 'pears', 'watermelons'}

答案 41 :(得分:0)

我已经将各种建议与 perfplot 进行了比较。事实证明,如果输入数组没有重复元素,则所有方法或多或少都一样快,与输入数据是 Python 列表还是 NumPy 数组无关。

enter image description here

如果输入数组很大,但只包含一个唯一元素,那么 setdictnp.unique 方法是共时时间如果输入数据是一个列表。如果是 NumPy 数组,则 np.unique 比其他替代方案快 10 倍左右。

enter image description here

令我惊讶的是,这些也不是恒定时间的操作。


重现情节的代码:

import perfplot
import numpy as np
import matplotlib.pyplot as plt


def setup_list(n):
    # return list(np.random.permutation(np.arange(n)))
    return [0] * n


def setup_np_array(n):
    # return np.random.permutation(np.arange(n))
    return np.zeros(n, dtype=int)


def list_set(data):
    return list(set(data))


def numpy_unique(data):
    return np.unique(data)


def list_dict(data):
    return list(dict.fromkeys(data))


b = perfplot.bench(
    setup=[
        setup_list,
        setup_list,
        setup_list,
        setup_np_array,
        setup_np_array,
        setup_np_array,
    ],
    kernels=[list_set, numpy_unique, list_dict, list_set, numpy_unique, list_dict],
    labels=[
        "list(set(lst))",
        "np.unique(lst)",
        "list(dict(lst))",
        "list(set(arr))",
        "np.unique(arr)",
        "list(dict(arr))",
    ],
    n_range=[2 ** k for k in range(23)],
    xlabel="len(array)",
    equality_check=None,
)
# plt.title("input array = [0, 1, 2,..., n]")
plt.title("input array = [0, 0,..., 0]")
b.save("out.png")
b.show()

答案 42 :(得分:0)

这只是一个可读的函数,易于理解,我使用了dict数据结构,我使用了一些内置函数,并且O(n)的复杂度更高

def undup(dup_list):
    b={}
    for i in dup_list:
        b.update({i:1})
    return b.keys()
a=["a",'b','a']
print undup(a)

disclamer:您可能会遇到缩进错误(如果复制并粘贴),请在粘贴之前使用上面的代码加上适当的缩进

答案 43 :(得分:0)

  • 您可以使用 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))

答案 44 :(得分:0)

my_list = [1, 2, 4, 4, 1, 4, 2, 6, 2, 9] final_list =[] 对于 my_list 中的 i: 如果我不在 final_list 中: final_list.append(i) print("只有唯一元素的列表:") 打印(final_list)

答案 45 :(得分:0)

Write a Python program to create a list of numbers by taking input from the user and then remove  the duplicates from the list. You can take input of non-zero numbers, with an appropriate  prompt, from the user until the user enters a zero to create the list assuming that the numbers  are non-zero.  
Sample Input: [10, 34, 18, 10, 12, 34, 18, 20, 25, 20]  
Output: [10, 34, 18, 12, 20, 25] 

 lst = []
print("ENTER ZERO NUMBER FOR EXIT !!!!!!!!!!!!")
print("ENTER LIST ELEMENTS  :: ")
while True:
    n = int(input())
    if n == 0 :
       print("!!!!!!!!!!! EXIT !!!!!!!!!!!!")
       break
    else :
        lst.append(n)
print("LIST ELEMENR ARE :: ",lst)
#dup = set()
uniq = []
for x in lst:
    if x not in uniq:
        uniq.append(x)
       # dup.add(x)
print("UNIQUE ELEMENTS IN LIST ARE :: ",uniq)

答案 46 :(得分:0)

检查字符串 'a' 和 'b'

clean_list = []
    for ele in raw_list:
        if 'b' in ele or 'a' in ele:
            pass
        else:
            clean_list.append(ele)

答案 47 :(得分:0)

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)

答案 48 :(得分:0)

它需要安装第三方模块,但包iteration_utilities包含unique_everseen 1 功能,可以在保留订单的同时删除所有重复项:

>>> from iteration_utilities import unique_everseen

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

如果您想避免列表添加操作的开销,可以使用itertools.chain代替:

>>> 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 - 库的作者。

答案 49 :(得分:0)

为了完整性,由于这是一个非常受欢迎的问题,toolz库提供了unique功能:

>>> tuple(unique((1, 2, 3)))
(1, 2, 3)
>>> tuple(unique((1, 2, 1, 3)))
(1, 2, 3)

答案 50 :(得分:0)

如果列表是有序的,则可以使用以下方法在其上进行迭代,从而跳过重复的值。这对于处理低内存消耗的大列表而避免构建dictset的成本特别有用:

def uniq(iterator):
    prev = None
    for item in iterator:
        if item != prev:
            prev = item
            yield item

然后:

for item in [1, 1, 3, 5, 5, 6]:
    print(item, end=' ')

输出将是:1 3 5 6

答案 51 :(得分:0)

有时您需要就地删除重复项,而无需创建新列表。例如,列表很大,或者将其保留为卷影副本

from collections import Counter
cntDict = Counter(t)
for item,cnt in cntDict.items():
    for _ in range(cnt-1):
        t.remove(item)

答案 52 :(得分:0)

def remove_duplicates(input_list):
  if input_list == []:
    return []
  #sort list from smallest to largest
  input_list=sorted(input_list)
  #initialize ouput list with first element of the       sorted input list
  output_list = [input_list[0]]
  for item in input_list:
    if item >output_list[-1]:
      output_list.append(item)
  return output_list   

答案 53 :(得分:0)

Python内置了许多函数,您可以使用set()删除列表中的重复项。 根据您的示例,下面有两个列表t和t2

t = ['a', 'b', 'c', 'd']
t2 = ['a', 'c', 'd']
result = list(set(t) - set(t2))
result

答案:['b']

答案 54 :(得分:-2)

list_with_unique_items = list(set(list_with_duplicates))