简体   繁体   English

减少不适用于collections.defaultdict吗?

[英]reduce not working for collections.defaultdict?

Why is reduce() is not working with a defaultdict object in the following case: 在以下情况下,为什么reduce()无法与defaultdict对象一起使用:

>>> from collections import defaultdict
>>> d = defaultdict(lambda: defaultdict(int))
>>> reduce(dict.get, [1,2], d)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: descriptor 'get' requires a 'dict' object but received a 'NoneType'

The above reduce is equivalent to d[1][2] , so I expected 0 , ie the default return value as output but I got a NoneType exception instead. 上面的reduce等效于d[1][2] ,所以我期望0 ,即默认返回值作为输出,但是我得到了NoneType异常。

If I use d[1][2] it works fine as shown below: 如果我使用d[1][2]则如下所示:

>>> d[1][2]
0

Am I doing anything wrong? 我做错什么了吗?

dict.get() returns None if a key is not present, even for a defaultdict object . 如果不存在键, 即使对于defaultdict对象dict.get()将返回None

That's because the job of dict.get() is to return a default value instead when a key is missing. 这是因为dict.get()工作是在缺少键时返回默认值。 If it didn't you'd never be able to return a different default (the second argument to dict.get() ): 如果没有,您将永远无法返回不同的默认值( dict.get()的第二个参数):

>>> from collections import defaultdict
>>> d = defaultdict(lambda: defaultdict(int))
>>> d.get(1, 'default')
'default'

In other words, your reduce(dict.get, ..) function is not the equivalent of the d[1][2] expression. 换句话说,您的reduce(dict.get, ..)函数等同于d[1][2]表达式。 It is the equivalent of d.get(1).get(2) , which fails the exact same way: 它等效于d.get(1).get(2) ,它以完全相同的方式失败:

>>> d = defaultdict(lambda: defaultdict(int))
>>> d.get(1).get(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'get'

Use dict.__getitem__ instead if you want to rely on the auto-insertion behaviour: 如果要依赖自动插入行为,请使用dict.__getitem__

>>> reduce(dict.__getitem__, [1,2], d)
0

The expression d[1] translates directly to d.__getitem__(1) . 表达式d[1]直接转换为d.__getitem__(1)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM