今天來(lái)和大家聊聊日常經(jīng)常使用到的偷懶方法 --> defaultdict
defaultdict示例
字典作為日常使用頻率較高的一種數(shù)據(jù)類(lèi)型,常會(huì)遇到判斷key是否在字典中的情況。
這時(shí),我們是否按照如下代碼寫(xiě)的:
d = dict()
if 'key' in d:
d['key'] += 1
else:
d['key'] = 0
print(d['key']) # 1
我們每次都需要判斷后再進(jìn)行相關(guān)操作。
但是,當(dāng)我們使用了defaultdict后,就可以偷懶的簡(jiǎn)化if else 的格式了:
from collections import defaultdict
d = defaultdict(int)
d["key"] += 1
print(d['key']) # 1
關(guān)于defaultdict
大家日常使用到defaultdict的場(chǎng)景,絕大多數(shù)都是上述舉例為了減少if else的判斷。
當(dāng)然除了默認(rèn)的int初始化,還有列表追加 d = defaultdict(list) 的無(wú)腦append操作。
可是,我們是否有深挖過(guò)defaultdict的其他場(chǎng)景呢?來(lái)先看看它的源碼:
def __init__(self, default_factory=None, **kwargs):
# known case of _collections.defaultdict.__init__
"""
defaultdict(default_factory=None, /, [...]) -->
dict with default factory
The default factory is called without arguments to produce
a new value when a key is not present, in __getitem__ only.
A defaultdict compares equal to a dict with the same items.
All remaining arguments are treated the same as if they were
passed to the dict constructor, including keyword arguments.
# (copied from class doc)
"""
pass
源碼注釋中,只是簡(jiǎn)單說(shuō)明了使用default_factory參數(shù),可以讓調(diào)用鍵不存在時(shí)生成新值。
就比如我們上面 defaultdict(int) 將key不存在時(shí),value默認(rèn)賦值0, d = defaultdict(list) 將key不存在時(shí),value默認(rèn)賦值空列表。
聽(tīng)起來(lái)功能就是如此了吧...
現(xiàn)在我們來(lái)?yè)Q個(gè)場(chǎng)景,拿同學(xué)們打力扣周賽舉個(gè)例子。
力扣周賽
每個(gè)人參加力扣周賽時(shí),會(huì)根據(jù)我們的比賽結(jié)果進(jìn)行評(píng)分。如果是第一次參加比賽,因?yàn)闆](méi)有初始積分,從0分開(kāi)始不太合適。
所以每位選手的初始基準(zhǔn)分為1500分。這樣就可以根據(jù)選手分?jǐn)?shù)來(lái)考量本次比賽表現(xiàn)進(jìn)行加分了。
先來(lái)看看默認(rèn)字典的代碼應(yīng)該如何操作:
scores = dict()
add_score = 10
# 方法1
if 'xiaoming' in scores:
scores['xiaoming'] += add_score
else:
scores['xiaoming'] = 1500 + add_score
# 方法2
scores['xiaoming'] = scores.get('xiaoming', 1500) + add_score
現(xiàn)在我們想使用defaultdict,但defaultdict如果賦值int,就沒(méi)辦法提供這個(gè)基準(zhǔn)分了,該如何是好?
此時(shí)我們應(yīng)該深入理解下 default_factory ,它不僅僅支持我們傳入默認(rèn)的int、list,還支持我們使用自定義函數(shù)。
from collections import defaultdict
def diy_func():
print("init user score.")
return 1500
scores = defaultdict(diy_func)
scores['xiaoming'] += 10
print(scores['xiaoming'])
# init user score.
# 1510
我們通過(guò)自定義一個(gè)函數(shù)賦值給 default_factory, 幫我們初始化用戶的分?jǐn)?shù)。
但這個(gè)自定義的函數(shù)方法有些太過(guò)單一了,是否可以簡(jiǎn)化?此時(shí)我們應(yīng)該考慮到lambda表達(dá)式??!
scores = defaultdict(lambda: 1500)
scores['xiaoming'] += 10
print(scores['xiaoming'])
這樣做是不是就更簡(jiǎn)潔方便了。有沒(méi)有覺(jué)得這操作很nice?
然而,我們注意到defaultdict的 __init__ 方法是存在 **kwargs** 參數(shù),我們還沒(méi)有使用呢!
它還可以這么玩:
from collections import defaultdict
data = defaultdict(xiaozhang=1600, xiaowang=1700)
scores = defaultdict(lambda: 1500, data)
scores['xiaoming'] += 10
scores['xiaowang'] -= 15
print(scores.items())
# dict_items([('xiaozhang', 1600), ('xiaowang', 1685), ('xiaoming', 1510)])
所以,defaultdcit可以在 使用 default_factory 的基礎(chǔ)上,導(dǎo)入初始的字典進(jìn)行。是不更溜了?
關(guān)于default_dict的內(nèi)容,今天就學(xué)到這里吧,希望對(duì)大家有所幫助。
歡迎關(guān)注我的公_眾號(hào): 清風(fēng)Python,帶你每日學(xué)習(xí)Python算法刷題的同時(shí),了解更多python小知識(shí)。
我的個(gè)人博客:https://qingfengpython.cn