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


当前回答

您可以比较集合和列表的长度,并将集合项保存到列表。

if len(t) != len(set(t)):
    t = [x for x in set(t)]
     

其他回答

从列表中删除重复项的最佳方法是使用set()函数,该函数在python中可用,再次将该集合转换为列表

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

您可以比较集合和列表的长度,并将集合项保存到列表。

if len(t) != len(set(t)):
    t = [x for x in set(t)]
     

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

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

如果输入数组很大,但只包含一个唯一元素,则set、dict和np。如果输入数据是一个列表,唯一方法是常量时间的。如果是NumPy数组,np。Unique比其他选项快10倍。

让我有点惊讶的是这些也不是常时间运算。


代码重现图:

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()

你也可以这样做:

>>> 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异常 这样的项目。