defaultdict:第一个参数必须是可调用的或无

Arc*_*yno 12 python defaultdict

我运行了以下代码:

from collections import defaultdict
lst = list(range(0,5))
d = defaultdict(lst)
Run Code Online (Sandbox Code Playgroud)

我收到了这个错误:

TypeError: first argument must be callable or None
Run Code Online (Sandbox Code Playgroud)

请帮忙

Wil*_*sem 16

对于defaultdict默认值通常不是一个真正的价值,它的工厂:产生一个新的价值的方法.您可以使用生成列表的lambda表达式来解决此问题:

lst = lambda:list(range(0,5))
d = defaultdict(lst)
Run Code Online (Sandbox Code Playgroud)

这也是一个好主意,因为否则所有默认值都会引用相同的列表.比如这里:

d[1].append(14)
Run Code Online (Sandbox Code Playgroud)

不会有冲击d[2](因为两者d[1]d[2]不存在).

但是,可以用:

val = list(range(0,5))
lst = lambda:val
d = defaultdict(lst)
Run Code Online (Sandbox Code Playgroud)

但是,这可能产生有害的副作用:如果你在这里进行d[1].append(14),然后d[2][1,2,3,4,5,14]d[1] is d[2]将是True:

$ python3
Python 3.5.2 (default, Nov 17 2016, 17:05:23) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from collections import defaultdict
>>> val = list(range(0,5))
>>> lst = lambda:val
>>> d = defaultdict(lst)
>>> d[1]
[0, 1, 2, 3, 4]
>>> d[1].append(14)
>>> d[2]
[0, 1, 2, 3, 4, 14]
>>> d[1] is d[2]
True
Run Code Online (Sandbox Code Playgroud)

然而:

$ python3
Python 3.5.2 (default, Nov 17 2016, 17:05:23) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from collections import defaultdict
>>> lst = lambda:list(range(0,5))
>>> d = defaultdict(lst)
>>> d[1]
[0, 1, 2, 3, 4]
>>> d[1].append(14)
>>> d[2]
[0, 1, 2, 3, 4]
>>> d[1] is d[2]
False
Run Code Online (Sandbox Code Playgroud)


Mos*_*oye 6

您应该使参数可调用,例如,使用lambda:

from collections import defaultdict

d = defaultdict(lambda: list(range(0,5)))
print(d[0])
# [0, 1, 2, 3, 4]
Run Code Online (Sandbox Code Playgroud)


And*_*yko 5

默认字典接受callable作为第一个参数(这是未定义值的默认工厂),因此下一步是要执行的操作:

from collections import defaultdict


default_factory = (lambda: list(range(0,5))
d = defaultdict(default_factory)
Run Code Online (Sandbox Code Playgroud)

在Python什么是“可调用”中了解有关可调用的更多信息这样的问题。