Python 的 collections.defaultdict returns 默认值是正确的,除非没有首先引用该键
Python's collections.defaultdict returns default value correctly unless the key isn't referenced first
基本上,如果我设置 defaultdict
并按键引用它,它将正常工作,return 我设置为默认值。但是,如果我在其上使用 .get()
,则默认值不是 returned。这是我能给出的最简单的例子。
basedict = defaultdict(dict)
assert(basedict['junk'] == {}) # Pass
assert(basedict.get('junk') == {}) # Pass
assert(basedict.get('popcorn') == {}) # Fail
为了完成,我正在处理一个个的字典,我最初遇到问题的代码看起来更像这样
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()
returns 一个空字典。
我最近 运行 遇到了这个问题,基本上不得不做这样的事情:
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
基本上,如果我设置 defaultdict
并按键引用它,它将正常工作,return 我设置为默认值。但是,如果我在其上使用 .get()
,则默认值不是 returned。这是我能给出的最简单的例子。
basedict = defaultdict(dict)
assert(basedict['junk'] == {}) # Pass
assert(basedict.get('junk') == {}) # Pass
assert(basedict.get('popcorn') == {}) # Fail
为了完成,我正在处理一个个的字典,我最初遇到问题的代码看起来更像这样
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()
returns 一个空字典。
我最近 运行 遇到了这个问题,基本上不得不做这样的事情:
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