【问题标题】:Python: Default list in functionPython:函数中的默认列表
【发布时间】:2017-04-06 12:38:52
【问题描述】:

来自 Summerfield 的 Python3 编程:

它是这样说的: 当给定默认值时,它们是在执行 def 语句时创建的,而不是在调用函数时创建的。 但我的问题是针对以下示例:

def append_if_even(x, lst =None):
    lst = [] if lst is None else lst
    if x % 2 ==0:
        lst.append(x)
    return lst

作为第一次执行的定义,lst 指向 None 但是在函数调用 append_if_even(2) 之后,

  • 不应 lst 指向 [2],因为在 lst.append(x) 之后 lst 不再指向 None 了?

  • 为什么下一次执行仍然让 lst 指向无?

  • 在这个函数调用 append_if_even(2) 中到底发生了什么?

【问题讨论】:

  • 参数xlst不是全局变量。所以设置它们对第二次调用没有影响
  • 就是函数创建后,会为这个函数的默认参数创建一个内存空间。当需要默认参数时,这个本地 lst 将被分配给值 None 的创建空间?这就是默认参数在 python 中的工作方式吗?
  • @wllLiu:嗯,只有一个None。但是假设您指定了lst = []。它将构建一个列表。如果您没有指定lstlst 将引用该列表。否则对给定的论点。但是设置参数本身没有影响。

标签: python-3.x default-arguments


【解决方案1】:

不应该指向 [2],因为在 lst.append(x) 之后 lst 不再指向 None 了?为什么下一次执行仍然让 lst 指向无?

这正是您通过使用lst=Nonelst = [] if lst is None else lst 构造来防止的。虽然函数的默认参数仅在编译时评估一次,但函数内的代码在每次执行函数时都会被评估。所以每次你在没有传递lst的值的情况下执行函数时,它将以None的默认值开始,然后当第一行的第一行时立即被一个new空列表替换函数被执行。

如果你改为这样定义函数:

def append_if_even(x, lst=None):
    if lst is None:
        lst = []
    if x % 2 == 0:
        lst.append(x)
    return lst

然后它会按照你的描述行事。 lst 的默认值将是函数每次运行的 same 列表(最初为空),并且传递给函数的每个偶数都将添加到一个不断增长的列表中。

有关详细信息,请参阅"Least Astonishment" and the Mutable Default Argument

【讨论】:

    猜你喜欢
    • 2013-08-11
    • 2015-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-19
    • 2022-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多