亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

從列表中刪除重復項,但考慮元素的類型并保留順序

從列表中刪除重復項,但考慮元素的類型并保留順序

慕斯王 2022-07-12 10:31:11
任務:開發一個clean_list (list_to_clean)函數,它接受 1 個參數 - 任意長度的任意值(字符串、整數和浮點數)的列表,并返回一個具有相同值但沒有重復項的列表。這意味著如果原始列表中存在多個實例中的值,則該值的第一個“實例”保留在原地,第二個、第三個等被刪除。例子:函數調用:clean_list ([32, 32.1, 32.0, -32, 32, '32']) 返回:[32, 32.1, 32.0, -32, '32']我的代碼:def clean_list(list_to_clean):   no_dubl_lst = [value for _, value in set((type(x), x) for x in list_to_clean)]   return no_dubl_lstprint(clean_list([32, 32.1, 32.0, -32, 32, '32']))結果:[32.1, 32, -32, 32.0, '32']但是我怎樣才能恢復原來的順序呢?
查看完整描述

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)


查看完整回答
反對 回復 2022-07-12
?
Helenr

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答案 - 在我創建答案時,他刪除/編輯/取消刪除了他的第一個內容更多的內容。


你會得到我的自動版本檢測,所以不要刪除它。


查看完整回答
反對 回復 2022-07-12
?
喵喔喔

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分析已發布的幾個答案。


查看完整回答
反對 回復 2022-07-12
  • 3 回答
  • 0 關注
  • 142 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號