Python-list在函数外部得到更新,而不使用";return";

Python-list在函数外部得到更新,而不使用";return";,python,list,variables,scope,namespaces,Python,List,Variables,Scope,Namespaces,我有一个列表,我给一个函数作为参数。 在函数内部,我正在更改列表,但我不会使用return返回列表。 我正在运行函数,然后打印列表 排除结果:[] 实际结果:[5] 这怎么可能 def foo(bar): for i in range(2): if bar == []: bar.append(4) else: bar[0] += 1 myvar = [] foo(myvar) p

我有一个列表,我给一个函数作为参数。 在函数内部,我正在更改列表,但我不会使用
return
返回列表。 我正在运行函数,然后打印列表

排除结果:
[]

实际结果:
[5]

这怎么可能

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

因为空列表首先在内存位置创建,第二次它引用相同的列表,而不是创建新的列表

  • 第一个栏=[]为空
  • 对于循环检查条是否为空,请向其添加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”附加到现有列表中。
这是因为,在定义函数时,函数参数的默认值只计算一次。
因此,只有在首次定义foo()时,bar参数才会初始化为其默认值(即空列表),但随后对foo()的调用将继续使用bar最初初始化到的相同列表。

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

列表1=[0,1,2,3] >>>list2=list1 >>>列表1[0]=5 >>>清单2 [5, 1, 2, 3] 这里,
list1
存储对列表的引用
[0,1,2,3]
,并且
list2
被赋予相同的引用。当通过
list1
中的引用修改列表时,
list2
引用的列表也会被修改

>>def foo(条形):
对于范围(2)中的i:
如果条==[]:
附加条(4)
其他:
条[0]+=1
>>>myvar=[]
>>>foo(myvar)
>>>迈瓦尔
[5]
将列表
myvar
作为参数
bar
传递给函数
foo()
,将指向列表的指针
[]
分配给参数
bar
。由于
myvar
bar
引用相同的列表,当通过
bar
修改列表时,通过
myvar
检索列表反映了相同的更改


希望这能澄清任何困惑

这一点也不奇怪<代码>栏传递在全局范围中定义的列表。当然,改变列表会改变它,因为正如你所说,你正在改变函数中的列表。“我在修改列表,为什么它会被修改?”“关于列表,需要知道的一件事是它们包含引用,而不是列表本身。”这没有任何意义。我想你想说的是,所有变量都是对象的引用。这与列表无关