3 回答

TA贡献1810条经验 获得超4个赞
这里有两个问题,所以为了回答的目的,我将两者都列出来。
尊重类型(你已经想通了)
删除列表中的重复项建议将中间体构造set为最快的方法。如果一个元素等于当前元素,则认为它存在于集合中。
在您的情况下,您不仅需要相等的值,还需要相等的类型。那么为什么不构造一个中间元组(value, type)呢?
unique_list = [v for v,t in {(v,type(v)) for v in orig_list}]
维持秩序
根据Python 是否有有序集,使用“有序集”容器?. 例如:
从 3.7 开始(以及 CPython 3.6,这是一个实现细节),常规dicts 保留插入顺序:
unique_list = [v for v,t in dict.fromkeys((v,type(v)) for v in orig_list)]
对于所有版本(也存在于 3.6+ 中,因为它具有其他方法),请使用collections.OrderedDict:
import collections
unique_list = [v for v,t in collections.OrderedDict.fromkeys((v,type(v)) for v in orig_list)]
作为参考,timeit我的机器(3.7.4 win64)上的结果与撰写本文时的其他答案相比:
In [24]: l=[random.choice((int,float,lambda v:str(int(v))))(random.random()*1000) for _ in range(100000)]
In [26]: timeit dict_fromkeys(l) #mine
38.6 ms ± 179 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [34]: timeit ordereddict_fromkeys(l) #mine with OrderedDict
53.3 ms ± 233 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [25]: timeit build_with_filter(l) #Ch3steR's O(n)
48.7 ms ± 214 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [28]: timeit dict_with_none(l) #Patrick Artner's
46.8 ms ± 377 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [30]: timeit listcompr_side_effect(l) #CDJB's
55.5 ms ± 801 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

TA贡献1780条经验 获得超4个赞
放入集合,检查集合的方法很好。您还可以将 anydict()用于 python 3.7+(键保持输入有序)或OrderedDict用于 3.7 以下的 python 版本:
def clean_list(list_to_clean):
ord_dic = dict
import sys
major,minor,_,_,_ = sys.version_info
if major < 3 or major == 3 and minor < 7:
# dict not yet input ordered
from collections import OrderedDict
no_dubl_lst = OrderedDict(((type(a),a),None) for a in list_to_clean)
else:
# dict is input ordered by default
no_dubl_lst = dict(((type(a),a),None) for a in list_to_clean)
return list(b for _,b in no_dubl_lst.keys()) # only produce the actual data
print(clean_list([32, 32.1, 32.0, -32, 32, '32']))
生产:
[32, 32.1, 32.0, -32, '32']
本质上,dict-keys 的行为就像在一个集合中一样(只会使用第一个,后面的会覆盖None第一个的值) - 但它们是有序的。
如果您在 3.7+ 上简单使用
def clean_list(list_to_clean):
# dict is input ordered by default
no_dubl_lst = dict(((type(a),a),None) for a in list_to_clean)
类似于ivan_pozdeev答案 - 在我创建答案时,他删除/编辑/取消删除了他的第一个内容更多的内容。
你会得到我的自动版本检测,所以不要删除它。

TA贡献1735条经验 获得超5个赞
你试试这个。
就像你问的第一个实例仍然在原地休息被删除。
(注意这个是O(n^2))
_list=[32, 32.1, 32.0, -32, 32, '32']
_clist=[]
for i in _list:
if (i,type(i),) not in _clist:
_clist.append((i,type(i),))
cleaned_list=list(zip(*_clist))[0]
print(cleaned_list)
#(32, 32.1, 32.0, -32, '32')
一种O(n)具有额外O(n)空间的方法。
_list=[32, 32.1, 32.0, -32, 32, '32']
unique=set()
cleaned=[]
for i in _list:
if (i,type(i),) not in unique:
unique.add((i,type(i),))
cleaned.append(i)
笔记:
请查看ivan_pozdeev的答案以timeit分析已发布的几个答案。
添加回答
举报