【问题标题】:Python - list gets updated outside function without using "return" [duplicate]Python - 列表在不使用“return”的情况下在函数外部更新[重复]
【发布时间】:2021-06-07 19:28:07
【问题描述】:

我有一个列表,我将其作为参数提供给函数。 在函数内部,我正在更改列表,但我没有使用return 返回列表。 我正在运行该函数并随后打印列表。

异常结果:[]

实际结果:[5]

这怎么可能?

def foo(bar):
    for i in range(2):
        if bar == []:
            bar.append(4)
        else:
            bar[0] += 1
            
myvar = []  
foo(myvar)
print (myvar)

【问题讨论】:

  • 这并不奇怪。 bar 被传递给在全局范围内定义的列表。当然改变这个列表会改变它
  • 因为,正如您所说,您正在更改函数内部的列表。
  • 阅读以下内容:nedbatchelder.com/text/names.html
  • 很奇怪的问题,tbh。 “我正在修改列表,为什么会被修改?”

标签: python list variables scope namespaces


【解决方案1】:

关于列表需要了解的一点是,它们包含指向列表对象而不是列表本身的引用(指针)。这可以通过运行以下代码来看到:

>>> list1 = [0, 1, 2, 3]
>>> list2 = list1
>>> list1[0] = 5
>>> list2
[5, 1, 2, 3]

这里,list1 存储对列表 [0, 1, 2, 3] 的引用,list2 被赋予相同的引用。通过list1中的引用修改列表时,list2引用的列表也被修改。

>>> def foo(bar):
        for i in range(2):
            if bar == []:
                bar.append(4)
            else:
                bar[0] += 1
            
>>> myvar = []  
>>> foo(myvar)
>>> myvar
[5]

将列表myvar 传递给函数foo() 作为参数bar 将指向列表[] 的指针分配给参数bar。由于myvarbar 引用了同一个列表,所以当通过bar 修改列表时,通过myvar 检索列表会反映相同的变化。

希望这可以澄清任何困惑!

【讨论】:

  • “关于列表要了解的一点是,它们包含引用而不是列表本身。”这没有任何意义。我认为您想说的是所有变量都充当对对象的引用。这与列表无关
【解决方案2】:

因为第一次在内存位置创建空列表,第二次它引用同一个列表而不是创建新列表。

  • 第一个栏 =[] 为空。
  • for 循环检查 bar 是否为空,添加 4。
  • 现在 bar = [4] 所以它再次检查 bar == [] 但现在它的值是 4。所以它进入 else 部分并添加 1。
  • 现在 bar 的值变为 5。
  • 在此过程中,它指的是同一内存位置。

以下示例将帮助您更好地理解它,

def foo (bar = []):
    bar.append('baz')
    return bar

foo()
['baz']


foo()

['baz', 'baz']


foo()
['baz', 'baz', 'baz']

每次调用 foo() 时,它都会将默认值“baz”附加到现有列表。
这是因为,函数参数的默认值仅在定义函数时计算一次。 因此,bar 参数仅在首次定义 foo() 时才被初始化为其默认值(即空列表),但随后调用 foo() 将继续使用最初初始化 bar 的相同列表。

【讨论】:

    猜你喜欢
    • 2013-07-26
    • 1970-01-01
    • 2015-10-07
    • 1970-01-01
    • 1970-01-01
    • 2021-10-05
    • 1970-01-01
    • 2014-10-02
    • 1970-01-01
    相关资源
    最近更新 更多