为什么collections.defaultdict的lambda没有参数?

时间:2016-08-17 06:36:05

标签: python lambda

在python中,我有以下代码行:

my_var = collections.defaultdict(lambda: collections.defaultdict(collections.defaultdict(float)))

我不明白它在做什么。我不明白的一件事是我们没有为lambda函数指定任何变量。

1 个答案:

答案 0 :(得分:3)

default_factory defaultdict 参数应该是一个不接受任何创建和返回对象的参数的函数,该对象将成为任何不存在的对象的值被引用的条目。

提供此类功能的一种方法是使用内联lambda expression创建匿名函数。另一种方法是使用创建的内置函数的名称并返回其中一个内置类型,例如floatinttuple等。当任何< em>那些在没有参数的情况下被调用,返回的对象的值将具有一些默认值 - 通常为零或空。

首先,您可以通过格式化代码来创建更具可读性的代码:

my_var = collections.defaultdict(
            lambda: collections.defaultdict(
                collections.defaultdict(float)))

然而,(以任何一种形式)它都是不正确的,因为一些defaultdict调用没有可调用的函数参数。因为Python是一种解释型语言,所以在尝试使用my_var之前,您不会知道这一点。例如:

my_var['level1']['level2']['level3'] = 42.

会导致:

TypeError: first argument must be callable or None

可以通过添加另一个lambda

来解决此问题
my_var = collections.defaultdict(
            lambda: collections.defaultdict(
                lambda: collections.defaultdict(float)))  # need lambda here, too

之后,前面的作业将不会被视为错误。

由于defaultdict是内置dict类的子类,因此您可以使用json模块来打印一个实例:

import collections

my_var = collections.defaultdict(
            lambda: collections.defaultdict(
                lambda: collections.defaultdict(float)))

import json  # for pretty printing dictionaries

# Auto-creates the 3 levels of dictionaries needed.
my_var['level1']['level2']['level3A'] = 42.

# Similar to above but additionally auto-creates a
# my_var['level1']['level2']['level3B'] entry with default value of 0.0
my_var['level1']['level2']['level3C'] = my_var['level1']['level2']['level3B'] + 1

print(json.dumps(my_var, indent=4))

输出:

{
    "level1": {
        "level2": {
            "level3A": 42.0, 
            "level3B": 0.0, 
            "level3C": 1.0
        }
    }
}

我认为你应该能够理解它现在的作用 - 但如果没有,请告诉我。