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


当前回答

有许多其他的答案提出了不同的方法,但它们都是批处理操作,其中一些会抛弃原始的顺序。这可能是可以的,这取决于你需要什么,但如果你想在每个值的第一个实例的顺序上迭代值,并且你想要立即删除重复的值而不是一次性删除,你可以使用这个生成器:

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

如果你想要一个列表,你可以这样做:

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]

其他回答

尝试使用集合:

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

print t | t1
print t - t1

另一种解决方案可能如下。以item为键,index为值,从列表中创建一个字典,然后打印字典键。

>>> lst = [1, 3, 4, 2, 1, 21, 1, 32, 21, 1, 6, 5, 7, 8, 2]
>>>
>>> dict_enum = {item:index for index, item in enumerate(lst)}
>>> print dict_enum.keys()
[32, 1, 2, 3, 4, 5, 6, 7, 8, 21]

也有使用Pandas和Numpy的解决方案。它们都返回numpy数组,所以如果你想要一个列表,你必须使用.tolist()函数。

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

熊猫的解决方案

唯一使用Pandas函数():

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是有序返回的。如果你想保留顺序,可以这样回答:

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

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

很晚才回答。 如果你不关心列表顺序,你可以使用*arg扩展集唯一性来删除dupes,即:

l = [*{*l}]

Python3演示

我没有看到非哈希值的答案,一行,nlog 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)))