你知道嗎?如果數(shù)組是字典組成的,直接對數(shù)組內(nèi)的字典采用set的方式進(jìn)行去重,會(huì)報(bào)錯(cuò):
test = [{"a": 1}, {"a": 1}, {"a": 3}, {"b": 4}]
test = list(set(test))
>>>TypeError: unhashable type: 'dict'
因?yàn)槭褂胹et去重的前提是該對象為不可變對象,而字典是可變對象,因此無法直接使用該方法去重。
那么怎么解決這個(gè)問題呢?有三個(gè)辦法。
1.使用reduce方法
reduce() 函數(shù)會(huì)對參數(shù)序列中元素進(jìn)行累積。
比如:
from functools import reduce
>>>def add(x, y) : # 兩數(shù)相加
... return x + y
...
>>>reduce(add, [1,2,3,4,5]) # 計(jì)算列表和:1+2+3+4+5
15
上述寫法也能用lambda函數(shù)簡化為:
from functools import reduce
>>> reduce(lambda x, y: x+y, [1,2,3,4,5]) # 使用 lambda 匿名函數(shù)
15
因此,我們自己編寫一個(gè)函數(shù)進(jìn)行數(shù)組內(nèi)的字典去重:
from functools import reduce
data = [{"a": 1}, {"a": 1}, {"a": 3}, {"b": 4}]
result = []
def unduplicate(result, data):
if data not in result:
result = result + [data]
return result
for i in data:
result = unduplicate(result, i)
>>> result
>>> [{'a': 1}, {'a': 3}, {'b': 4}]
稍顯復(fù)雜,如果使用reduce函數(shù)和lambda函數(shù),代碼能簡化很多:
def delete_duplicate(data):
func = lambda x, y: x + [y] if y not in x else x
data = reduce(func, [[], ] + data)
return data
>>> delete_duplicate(data)
>>> [{'a': 1}, {'a': 3}, {'b': 4}]
當(dāng)然, 我也能一行寫完這個(gè)功能:
data = reduce(lambda x, y: x + [y] if y not in x else x, [[], ] + data)
只不過有可能會(huì)被打死在工位上,所以不建議這么干。
2.奇怪的技巧
就如文章開頭提到的,字典之所以不能用set去重,是因?yàn)樗强勺儗ο蟆?/p>
但是...如果我們把它變成不可變對象呢?
data = [{"a": 1}, {"a": 1}, {"a": 3}, {"b": 4}]
def delete_duplicate(data):
immutable_dict = set([str(item) for item in data])
data = [eval(i) for i in immutable_dict]
return data
>>> delete_duplicate(data)
>>> [{'a': 1}, {'a': 3}, {'b': 4}]
沒錯(cuò),這能成。
1.遍歷字典,將每個(gè)子項(xiàng)變成字符串存放到數(shù)組中,再通過set函數(shù)去重。
2.通過eval函數(shù),將去重后的數(shù)組里的每個(gè)子項(xiàng)重新轉(zhuǎn)化回字典。
如此Python,怎能不好玩?
3.高效的方式
上面講了兩種騷操作,其實(shí)都不太建議在實(shí)際工作中使用。
一個(gè)原因是真的太騷了,怕被打趴在工位上。
另一個(gè)原因是,它們在應(yīng)對較大數(shù)據(jù)量的時(shí)候,性能不太行。
下面是最正統(tǒng)的方式:
data = [dict(t) for t in set([tuple(d.items()) for d in data])]
>>>data
>>>[{'a': 1}, {'b': 2}]
其實(shí)和第二種方式一樣,是將數(shù)組內(nèi)的每個(gè)字典轉(zhuǎn)成元組,也就是不可變對象,再使用set進(jìn)行去重。去重完畢后再使用dict函數(shù)將元組重新組成字典對。
但是,這種方法對于字典內(nèi)還有字典的數(shù)據(jù)結(jié)構(gòu)是不適用的,因此對于字典對里還有字典情況的去重,比如:
data2 = [{"a": {"b": "c"}}, {"a": {"b": "c"}}]
這種情況我建議使用第二種方式去重:
data2 = [{"a": {"b": "c"}}, {"a": {"b": "c"}}]
def delete_duplicate_str(data):
immutable_dict = set([str(item) for item in data])
data = [eval(i) for i in immutable_dict]
return data
print(delete_duplicate_str(data2))
>>> [{'a': {'b': 'c'}}]
怎么樣,這三種方式你都學(xué)會(huì)了嗎?
如果覺得有收獲的話記得收藏一下。以后遇到類似的去重場景時(shí)可以拿出閱讀一下。
我們的文章到此就結(jié)束啦,如果你喜歡今天的Python 實(shí)戰(zhàn)教程,請持續(xù)關(guān)注Python實(shí)用寶典。
-
對象
+關(guān)注
關(guān)注
1文章
38瀏覽量
17424 -
字典
+關(guān)注
關(guān)注
0文章
13瀏覽量
7724 -
SET
+關(guān)注
關(guān)注
0文章
17瀏覽量
7987
發(fā)布評(píng)論請先 登錄
相關(guān)推薦
python字典
python字典高階用法
python合并字典的 7 種方法
數(shù)組中的變量取值范圍如何進(jìn)行糾正
python字典類型的使用和注意事項(xiàng)
![<b class='flag-5'>python</b><b class='flag-5'>字典</b>類型的使用和注意事項(xiàng)](https://file.elecfans.com/web1/M00/B3/22/o4YBAF4cPSSAfUbdAADaSvHURVs576.png)
python字典是什么
簡述python字典映射嵌套排序和判斷
Python序列的字典類型介紹
![<b class='flag-5'>Python</b>序列的<b class='flag-5'>字典</b>類型介紹](https://file1.elecfans.com/web2/M00/81/C4/wKgaomQEYkOAbaIvAAGnfu9fq-A904.jpg)
評(píng)論