我如何检查一个列表是否有任何重复,并返回一个没有重复的新列表?
当前回答
如果列表是有序的,则可以使用以下方法对其进行迭代,跳过重复的值。这对于处理内存消耗低的大列表特别有用,可以避免构建dict或set的成本:
def uniq(iterator):
prev = None
for item in iterator:
if item != prev:
prev = item
yield item
然后:
for item in uniq([1, 1, 3, 5, 5, 6]):
print(item, end=' ')
输出将是:1 3 5 6
要返回一个列表对象,你可以这样做:
>>> print(list(uniq([1, 1, 3, 5, 5, 6])))
[1, 3, 5, 6]
其他回答
不使用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)
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']
]
因为元组是可哈希的,你可以很容易地在列表和元组之间转换数据
如果你不关心顺序,就这样做:
def remove_duplicates(l):
return list(set(l))
一个集合保证没有重复项。
我已将各种建议与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()
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
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用pip3安装包时,“Python中的ssl模块不可用”
- 无法切换Python与pyenv
- Python if not == vs if !=
- 如何从scikit-learn决策树中提取决策规则?
- 为什么在Mac OS X v10.9 (Mavericks)的终端中apt-get功能不起作用?
- 将旋转的xtick标签与各自的xtick对齐
- 为什么元组可以包含可变项?
- 如何合并字典的字典?
- 如何创建类属性?
- 不区分大小写的“in”
- 在Python中获取迭代器中的元素个数
- 解析日期字符串并更改格式
- 使用try和。Python中的if
- 如何在Python中获得所有直接子目录