Python defaultdict和lambda

use*_*006 53 python collections defaultdict

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

x = defaultdict(lambda: 0)
y = defaultdict(lambda: defaultdict(lambda: 0))
Run Code Online (Sandbox Code Playgroud)

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

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

Fre*_*Foo 48

我认为第一行意味着当我调用x[k]一个不存在的键k(例如类似语句v=x[k])时,键值对(k,0)将自动添加到字典中,就像x[k]=0首次执行该语句一样.

那就对了.这更具惯用性

x = defaultdict(int)
Run Code Online (Sandbox Code Playgroud)

在执行此y操作时y["ham"]["spam"],如果密钥不存在,"ham"则插入密钥y.与之关联的值变为a defaultdict,其中"spam"自动插入值为0.

即,y是一种"双层" defaultdict.如果"ham" not in y,那么评估y["ham"]["spam"]就像在做

y["ham"] = {}
y["ham"]["spam"] = 0
Run Code Online (Sandbox Code Playgroud)

就普通而言dict.

  • 在不使用lambda的情况下创建像`y`这样的deafultdict的另一种方法是使用`functools`中的[`partial`](http://docs.python.org/library/functools.html#functools.partial),如下所示: `y = defaultdict(partial(defaultdict,int))` (5认同)
  • @briandk:因为`int()`返回零. (3认同)

And*_*ark 8

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

y = defaultdict(lambda: defaultdict(lambda: 0))
print y['k1']['k2']   # 0
print dict(y['k1'])   # {'k2': 0}
Run Code Online (Sandbox Code Playgroud)

要创建一个没有defaultdict的等效嵌套字典结构,你需要创建一个内部字典y['k1']然后设置y['k1']['k2']为0,但是当遇到它没有看到的键时,defaultdict会在幕后完成所有这些:

y = {}
y['k1'] = {}
y['k1']['k2'] = 0
Run Code Online (Sandbox Code Playgroud)

以下功能可能有助于在翻译上玩这个以更好地理解:

def to_dict(d):
    if isinstance(d, defaultdict):
        return dict((k, to_dict(v)) for k, v in d.items())
    return d
Run Code Online (Sandbox Code Playgroud)

这将返回与嵌套的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}}
Run Code Online (Sandbox Code Playgroud)


Tri*_*ych 7

defaultdict 将零参数可调用到其构造函数,当找不到键时调用该构造函数,正如您正确解释的那样.

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

至于第二部分,defaultdict(int)只要在顶级字典中找不到密钥,作者就想创建一个新的或嵌套的字典.

  • 在这种情况下,@ mjb - int是首选,因为它更具可读性.使用int可能也快一点,但主要原因是它的代码更清晰. (4认同)
  • 通过docs.python.org:"总是返回零的函数int()只是常量函数的一种特殊情况.创建常量函数的更快更灵活的方法是使用itertools.repeat()来提供任何常量值(不只是零)".然后显示一个itertools.repeat()示例,这非常好.我建议阅读:http://docs.python.org/2/library/collections.html#defaultdict-objects (3认同)

Pra*_*hak 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
Run Code Online (Sandbox Code Playgroud)