90

在别人的代码中,我阅读了以下两行:

x = defaultdict(lambda: 0)
y = defaultdict(lambda: defaultdict(lambda: 0))

由于 defaultdict 的参数是一个默认工厂,我认为第一行的意思是当我为一个不存在的键 k 调用 x[k] 时(例如像 v=x[k] 这样的语句),键值对(k ,0) 将自动添加到字典中,就像首先执行语句 x[k]=0 一样。我对么?

那你呢?似乎默认工厂将创建一个默认为 0 的 defaultdict。但这具体意味着什么?我试图在 Python shell 中使用它,但无法弄清楚它到底是什么。

4

5 回答 5

78

我认为第一行的意思是当我调用x[k]一个不存在的键时k(例如像这样的语句v=x[k]),键值对(k,0)会自动添加到字典中,就好像该语句x[k]=0首先执行一样。

这是正确的。这写得更惯用

x = defaultdict(int)

在 的情况下y,当您这样做时y["ham"]["spam"],如果密钥不存在,则将其"ham"插入。y与它关联的值变成defaultdict,其中"spam"会自动插入 的值0

即,y是一种“两层” defaultdict。如果"ham" not in y,那么评估y["ham"]["spam"]就像做

y["ham"] = {}
y["ham"]["spam"] = 0

就普通而言dict

于 2011-12-07T17:08:11.487 回答
12

您对第一个所做的事情是正确的。至于y,它会在 中不存在键时创建一个默认为 0 的 defaultdict y,因此您可以将其视为嵌套字典。考虑以下示例:

y = defaultdict(lambda: defaultdict(lambda: 0))
print y['k1']['k2']   # 0
print dict(y['k1'])   # {'k2': 0}

要创建一个没有 defaultdict 的等效嵌套字典结构,您需要创建一个内部 dict y['k1'],然后设置y['k1']['k2']为 0,但是 defaultdict 在遇到未见过的键时会在后台执行所有这些操作:

y = {}
y['k1'] = {}
y['k1']['k2'] = 0

以下功能可能有助于在解释器上使用它以更好地理解:

def to_dict(d):
    if isinstance(d, defaultdict):
        return dict((k, to_dict(v)) for k, v in d.items())
    return d

这将返回与嵌套的 defaultdict 等效的 dict,它更容易阅读,例如:

>>> y = defaultdict(lambda: defaultdict(lambda: 0))
>>> y['a']['b'] = 5
>>> y
defaultdict(<function <lambda> at 0xb7ea93e4>, {'a': defaultdict(<function <lambda> at 0xb7ea9374>, {'b': 5})})
>>> to_dict(y)
{'a': {'b': 5}}
于 2011-12-07T17:16:20.360 回答
9

defaultdict正如您正确解释的那样,它的构造函数采用可调用的零参数,当找不到密钥时调用该构造函数。

lambda: 0当然总是会返回零,但是这样做的首选方法是defaultdict(int),它会做同样的事情。

defaultdict(int)至于第二部分,每当在顶级字典中找不到键时,作者想创建一个新的或嵌套字典。

于 2011-12-07T17:10:09.620 回答
5

所有答案都足够好,我仍然给出答案以添加更多信息:

“defaultdict 需要一个可调用的参数。该可调用对象的返回结果是当您尝试使用不存在的键访问字典时字典返回的默认值。”

这是一个例子

SAMPLE= {'Age':28, 'Salary':2000}
SAMPLE = defaultdict(lambda:0,SAMPLE)

>>> SAMPLE
defaultdict(<function <lambda> at 0x0000000002BF7C88>, {'Salary': 2000, 'Age': 28})

>>> SAMPLE['Age']----> This will return 28
>>> SAMPLE['Phone']----> This will return 0   # you got 0 as output for a non existing key inside SAMPLE
于 2018-03-08T23:57:15.523 回答
3

y = defaultdict(lambda:defaultdict(lambda:0))

如果你试试这个会很有帮助y['a']['b'] += 1

于 2015-01-13T08:43:53.200 回答