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分析已發布的幾個答案。
添加回答
舉報