在函数调用之间保存本地对象值(可能是范围误解)

时间:2016-01-28 20:17:36

标签: python recursion return scopes

我很困惑,试图解决"压扁"列表清单。
例如,我有一个列表[1,[2,2,2],4] - 我需要将它转换为[1,2,2,2,4]。
我解决了它那样:

def flat_list(array, temp_list=[]):
    for item in array:
        if str(item).isdigit():
            temp_list.append(item)
        else:
            temp_list = flat_list(item, temp_list)

    return temp_list

但是当我测试它时:

assert flat_list([1, 2, 3]) == [1, 2, 3]
assert flat_list([1, [2, 2, 2], 4]) == [1, 2, 2, 2, 4]
assert flat_list([[[2]], [4, [5, 6, [6], 6, 6, 6], 7]]) == [2, 4, 5, 6, 6, 6, 6, 6, 7]

" temp_list"的值正在函数调用之间传输。 " temp_list"的值在第二个断言的开头是[1,2,3] - "返回"第一个断言 - 但不是" []"。

我猜,这是因为我对范围有一些误解,并且"返回"指导,但我不明白到底是什么。

1 个答案:

答案 0 :(得分:1)

这是Python中的一个已知问题。

  

默认参数值始终在且仅当时才计算   他们所属的“def”声明被执行

参考:http://effbot.org/zone/default-values.htm

在您的代码示例中,执行temp_list语句时会计算def的默认值。因此它被设置为一个空列表。在后续调用中,列表会不断增长,因为temp_list的默认值不再被评估,并且它会继续使用它第一次创建的列表实例。

这可能是一种解决方法:

def flat_list(array, temp_list=None):
    if not temp_list:
         temp_list = []

    for item in array:
        if str(item).isdigit():
            temp_list.append(item)
        else:
            temp_list = flat_list(item, temp_list)

    return temp_list

在这里,我们已经通过None而不是空列表。然后在函数体内部检查值并根据需要初始化一个空列表。