也許你低估了defaultdict的偷懶能力!

今天來(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

力扣解題合集:https://github.com/BreezePython/AlgorithmMarkdown

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容