【问题标题】:Local object value is being saved between function calls (maybe scopes misunderstanding) [duplicate]在函数调用之间保存本地对象值(可能是范围误解)[重复]
【发布时间】:2016-05-06 09:38:17
【问题描述】:

我很困惑试图解决“扁平化”列表列表的任务。
例如,我有一个列表 [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] - 第一个断言的 "return" 的值 - 但不是 "[]"。

我猜,这是因为我对范围和“返回”指令有一些误解,但我不明白到底是什么。

【问题讨论】:

    标签: python recursion return scopes


    【解决方案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 而不是空列表。然后在函数体内,我们检查值并根据需要初始化一个空列表。

    【讨论】:

    • 是的,你是assert-ing 那些函数调用返回的值。所以这些是同一个函数的多次执行。
    • 每个后续断言都取前一个断言的返回值?据我了解,我需要阅读您的“参考”)
    • 每个断言调用一次函数。
    猜你喜欢
    • 2012-06-11
    • 2020-11-02
    • 2017-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-23
    • 2020-04-07
    相关资源
    最近更新 更多