【问题标题】:defaultdict : first argument must be callable or Nonedefaultdict : 第一个参数必须是可调用的或无
【发布时间】:2017-06-27 12:43:58
【问题描述】:

我运行了以下代码:

from collections import defaultdict
lst = list(range(0,5))
d = defaultdict(lst)

我得到了这个错误:

TypeError: first argument must be callable or None

请帮忙

【问题讨论】:

    标签: python defaultdict


    【解决方案1】:

    您应该使用lambda 使参数成为可调用的:

    from collections import defaultdict
    
    d = defaultdict(lambda: list(range(0,5)))
    print(d[0])
    # [0, 1, 2, 3, 4]
    

    【讨论】:

      【解决方案2】:

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

      lst = lambda:list(range(0,5))
      d = defaultdict(lst)

      这也是一个好主意,因为否则所有默认值引用同一个列表。例如这里:

      d[1].append(14)
      

      不会d[2] 产生影响(假设d[1]d[2] 都不存在)。

      可以通过以下方式实现这一目标

      val = list(range(0,5))
      lst = lambda:val
      d = defaultdict(lst)
      

      但这可能会产生不必要的副作用:如果您在这里执行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
      

      而:

      $ 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
      

      【讨论】:

      • 很好解释。
      • 所以我不能在现有列表上使用 defaultdict,比如a = [5,2,3] ?
      • @Arcyno:据我所知没有。请注意,在这种情况下,所有默认值将引用相同的列表
      【解决方案3】:

      Default dictionary 接受 callable 作为第一个参数(这是未定义值的默认工厂),所以您要做的是下一步:

      from collections import defaultdict
      
      
      default_factory = (lambda: list(range(0,5))
      d = defaultdict(default_factory)
      

      What is a "callable" in Python? SO question 中查看有关可调用的更多信息。

      【讨论】:

        猜你喜欢
        • 2017-04-04
        • 2020-08-31
        • 1970-01-01
        • 2021-03-20
        • 2020-03-08
        • 2018-01-05
        • 1970-01-01
        • 2021-12-18
        • 1970-01-01
        相关资源
        最近更新 更多