簡體   English   中英

dict 和 collections.defaultdict 有什么區別?

[英]What is the difference between dict and collections.defaultdict?

我正在查看 Peter Norvig 關於如何編寫簡單拼寫檢查器的代碼 一開始,他使用此代碼將單詞插入字典。

def train(features):
    model = collections.defaultdict(lambda: 1)
    for f in features:
        model[f] += 1
    return model

Python 字典和這里使用的字典有什么區別? 另外, lambda是干什么用的? 我在這里查看了 API 文檔,它說 defaultdict 實際上是從 dict 派生的,但是如何決定使用哪一個?

不同之處在於,如果尚未設置該鍵,則defaultdict將“默認”一個值。 如果您沒有使用defaultdict ,則必須檢查該鍵是否存在,如果不存在,請將其設置為您想要的。

lambda 正在為默認值定義工廠。 每當需要默認值時,都會調用 function 。 您可以假設有一個更復雜的默認 function。

Help on class defaultdict in module collections:

class defaultdict(__builtin__.dict)
 |  defaultdict(default_factory) --> 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.
 |  

(來自help(type(collections.defaultdict()))

{}.setdefault本質上類似,但接受一個值而不是工廠 function。 如果該值尚不存在,則用於設置該值……不過,這有點不同。

禮貌:- https://shirishweb.wordpress.com/2017/05/06/python-defaultdict-versus-dict-get/

使用普通字典

d={}
d['Apple']=50
d['Orange']=20
print(d['Apple'])
print(d['Grapes'])# This gives Key Error

我們也可以通過在普通字典中使用默認值來避免這個 KeyError,讓我們看看如何做到這一點

d={}
d['Apple']=50
d['Orange']=20
print(d['Apple'])
print(d.get('Apple'))
print(d.get('Grapes',0)) # DEFAULTING

使用默認字典

from collections import defaultdict
d = defaultdict(int) ## inside parenthesis we say what should be the default value.
d['Apple']=50
d['Orange']=20
print(d['Apple'])
print(d['Grapes']) ##→ This gives Will not give error

使用用戶定義的 function 來默認值

from collections import defaultdict
def mydefault():
        return 0

d = defaultdict(mydefault)
d['Apple']=50
d['Orange']=20
print(d['Apple'])
print(d['Grapes'])

概括

  1. 普通字典中的默認值視具體情況而定,在默認字典中,我們可以以一般方式提供默認值

  2. 通過 defaultdict 使用默認值的效率是使用普通 dict 進行默認值的兩倍。 您可以參考以下鏈接以更好地了解此性能測試https://shirishweb.wordpress.com/2017/05/06/python-defaultdict-versus-dict-get/

如果您對缺少的鍵有一些有意義的默認值並且不想明確處理它們,請使用 defaultdict。

defaultdict 構造函數將 function 作為參數,並使用該 function 構造一個值。

lambda: 1

與執行此操作的無參數 function f 相同

def f():
 return 1

我忘記了 API 以這種方式設計的原因,而不是將值作為參數。 如果我設計了defaultdict接口,會稍微復雜一些,缺失值創建function會把缺失的key作為參數。

讓我們深入了解 Python 字典和 Python defaultdict() class

Python 字典

Dict 是 Python 中可用的數據結構之一,它允許以鍵值對的形式存儲數據。

例子:

d = {'a': 2, 'b': 5, 'c': 6}

字典問題

除非您遇到丟失的鍵,否則字典會很好地工作。 假設您正在尋找字典中沒有值的鍵值對 - 那么您可能會遇到KeyError問題。 像這樣的東西:

d = {'a': 2, 'b': 5, 'c': 6}
d['z']  # z is not present in dict so it will throw a error

你會看到這樣的東西:

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
    d['z'] 
KeyError: 'z'

解決上述問題

為了克服上述問題,我們可以使用不同的方法:

使用內置函數

setdefault

如果key在字典中,則返回其值。 如果不是,則插入一個值為default的鍵並返回default default默認為None

>>> d = {'a' :2, 'b': 5, 'c': 6}
>>> d.setdefault('z', 0)
0  # returns 0 
>>> print(d)  # add z to the dictionary
{'a': 2, 'b': 5, 'c': 6, 'z': 0}

get

如果鍵在字典中,則返回key的值,否則返回default 如果未給出默認值,則默認為None ,因此此方法永遠不會引發KeyError

>>> d = {'a': 2, 'b': 5, 'c': 6}
>>> d.get('z', 0)
0  # returns 0 
>>> print(d)  # Doesn't add z to the dictionary unlike setdefault
{'a': 2, 'b': 5, 'c': 6}

以上2種方法是解決我們問題的方法。 它永遠不會引發KeyError 除了以上2種方法,Python還有一個collections模塊可以解決這個問題。 讓我們深入挖掘 collections 模塊中的defaultdict

defaultdict

defaultdict可以在 Python 的 collections 模塊中找到。 您可以使用它:

from collections import defaultdict

d = defaultdict(int)

defaultdict構造函數將default_factory作為可調用的參數。 例如,這可以是:

  • int :默認為 integer 值為0

  • str : 默認為空字符串""

  • list : 默認為空列表[]

代碼:

from collections import defaultdict

d = defaultdict(list)
d['a']  # access a missing key and returns an empty list
d['b'] = 1 # add a key-value pair to dict
print(d)

output 將是defaultdict(<class 'list'>, {'b': 1, 'a': []})

defaultdictget()setdefault()方法的工作方式相同,那么什么時候使用它們呢?

何時使用get()

如果您特別需要在沒有KeyError的情況下返回某個鍵值對並且它不應該在字典中更新 - 那么dict.get是您的正確選擇。 它返回您指定的默認值,但不修改字典。

何時使用setdefault()

如果您需要使用默認鍵值對修改原始字典 - 那么setdefault是正確的選擇。

何時使用defaultdict

setdefault方法可以使用defaultdict來實現,但不是每次都在setdefault中提供默認值,我們可以在defaultdict中一次完成。 此外, setdefault可以選擇為鍵提供不同的默認值。 兩者都有自己的優勢,具體取決於用例。

在效率方面:

defaultdict > setdefault()get()

defaultdictget()快 2 倍!

你可以在這里查看結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM