簡體   English   中英

Python的collections.defaultdict正確返回默認值,除非未首先引用該鍵

[英]Python's collections.defaultdict returns default value correctly unless the key isn't referenced first

基本上,如果我設置了defaultdict並通過鍵引用它,它將正常工作並返回我設置為默認值的值。 但是,如果在其上使用.get() ,則不會返回默認值。 這是我能給出的最簡單的例子。

basedict = defaultdict(dict)
assert(basedict['junk'] == {}) # Pass
assert(basedict.get('junk') == {}) # Pass
assert(basedict.get('popcorn') == {}) # Fail

為了完成操作,我正在使用dict的dict,而我最初遇到問題的代碼看起來更像這樣

from collections import defaultdict

basedict = defaultdict(dict)
assert(basedict['junk'] == {})

basedict[69] = defaultdict(lambda: 1000)
assert(basedict[69]['junk'] == 1000)
assert(basedict[69].get('junk') == 1000)
assert(basedict[69].get('junk', 420) == 1000)

# The above works fine, but if I call .get on a default dict using a key I've
# never referenced before it returns None or the .get supplied default value
assert(basedict[69].get('garbage') == 1000) # Returns None
assert(basedict[69].get('garbage', 420) == 1000) # Returns 420
assert(basedict[69].get('dumpster', 420) == 1000) # Returns 420

# But if I place a an assert before the calling .get(garbage) that 
# checks basedict[69]['garbage'] then the asserts after work until I get 
# to 'dumpster' at which point it fails again
# It also fails if I set the defaultdict to something other than a lambda
basedict[7] = defaultdict(dict)
assert(basedict[7]['taco'] == {}) # Pass
assert(basedict[7].get('taco') == {}) # Pass
assert(basedict[7].get('burrito') == {}) # Fail

defaultdict.get() 填充的關鍵,沒有。 這是設計使然 ,否則會破壞該方法的目的。 成員資格測試也是如此:

>>> from collections import defaultdict
>>> d = defaultdict(dict)
>>> 'foo' in d
False
>>> d['foo']
{}
>>> 'foo' in d
True

如果您需要為缺少的鍵調用默認工廠,請使用defaultdict.__getitem__ (例如defaultdict_instance[key] )。

如果需要設置工廠提供的默認值以外的其他值,請使用dict.setdefault()

>>> d = defaultdict(dict)
>>> d.setdefault('bar', 42)
42
>>> d.setdefault('bar', 30)
42
>>> d
defaultdict(<type 'dict'>, {'bar': 42})

如果您只需要獲取默認值,請使用dict.get()

>>> d = defaultdict(dict)
>>> d.get('bar', {}).get('baz', 1000)
1000

注意,我鏈接了.get()調用; 如果缺少第一個鍵,則第一個.get()返回一個空字典。

我最近遇到了這個問題,基本上必須做這樣的事情:

from collections import defaultdict

class BetterDict(defaultdict):
    def get(self, item, default=None):
        # default is not really used, but leaving here for compatibility
        # This will either return the actual value, or the defaultdict's
        # default, as generated by default_factory
        return self.__getitem__(item)

現在:

basedict = BetterDict(dict)
assert(basedict['junk'] == {}) # Pass
assert(basedict.get('junk') == {}) # Pass
assert(basedict.get('popcorn') == {}) # Pass

暫無
暫無

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

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