基本上,如果我设置defaultdict
并按键引用它,它将正常工作并返回我设置为默认值。但是,如果我在其上使用.get()
,则不会返回默认值。这是我能给出的最简单的例子。
basedict = defaultdict(dict)
assert(basedict['junk'] == {}) # Pass
assert(basedict.get('junk') == {}) # Pass
assert(basedict.get('popcorn') == {}) # Fail
为了完成,我正在使用dicts和我的代码,我最初遇到的问题看起来有点像这样
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
答案 0 :(得分:4)
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()
返回一个空字典。
答案 1 :(得分:1)
我最近遇到了这个问题,基本上必须做这样的事情:
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