传递给函数时列表会发生什么?

rne*_*s12 4 python function list

我试图理解当作为函数的参数传递时如何处理列表.所以我做的是以下内容:

我初始化了一个列表:

ll = [1,2,3,4] 
Run Code Online (Sandbox Code Playgroud)

并定义一个函数:

def Foo(ar):
    ar += [11]
Run Code Online (Sandbox Code Playgroud)

我将列表传递给函数:

Foo(ll)
Run Code Online (Sandbox Code Playgroud)

当我打印它时,我得到了:

print ll # [1, 2, 3, 4, 11] #case(1)
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.

现在我修改了函数以重置列表,使其只有一个元素:

def Foo(ar):
    ar = [11]
Run Code Online (Sandbox Code Playgroud)

我记得语法:

Foo(ll)
Run Code Online (Sandbox Code Playgroud)

当我重新打印它时,它产生了相同的列表:

print ll # [1, 2, 3, 4] # case(2)
Run Code Online (Sandbox Code Playgroud)

我以为列表是作为参考传递的; 所以无论我们对函数内的列表做什么都会改变从主程序传递的原始函数.因此,对于案例(2),我期待以下结果:

print ll # [11] # case(2) expected result
Run Code Online (Sandbox Code Playgroud)

我在这里错过了什么吗?

Bak*_*riu 7

ar += [11]不是只是一个分配.这是一个方法调用(名为is的方法__iadd__).当Python执行该行时,它调用该方法,然后分配ar给结果.修改当前的__iadd__方法.list list

ar = [11]是一个赋值,因此它只是更改本地名称ar的值.但是ar函数内部的名称和ll变量的值之间没有任何联系.

你可能想要这样的东西:

ar[:] = [11]
Run Code Online (Sandbox Code Playgroud)


rod*_*igo 5

您必须区分对象对象名称.Python中的列表是可变对象,因此只要有引用它们就可以更改它们.

名称只是对象的引用.请记住,在Python中,技术上没有变量,只有名称和对象,并且对象绑定到名称.

所以,考虑到这一点,让我们看看你的代码:

def Foo1(ar):
    ar += [11]
Run Code Online (Sandbox Code Playgroud)

此函数采用列表,将其绑定到本地名称ar,然后修改列表,添加新值.

但是这个其他代码:

def Foo2(ar):
    ar = [11]
Run Code Online (Sandbox Code Playgroud)

此函数采用绑定到ar名称的列表,然后将名称ar重新绑定到具有一个值的新列表.原始对象在此函数内未经修改且为fogotten.

然后你做的时候:

a = [1,2,3]
Run Code Online (Sandbox Code Playgroud)

然后打电话:

Foo1(a)
Run Code Online (Sandbox Code Playgroud)

修改列表添加新值,但是:

Foo2(a)
Run Code Online (Sandbox Code Playgroud)

没有任何价值a.

如果要编写一个用另一个替换列表中所有内容的函数,可以使用:

def Foo3(a):
    a[:] = [11]
Run Code Online (Sandbox Code Playgroud)

此代码不重新绑定,a但通过使用新列表替换内容来修改列表.

为了进一步说明我的观点,请看这个例子:

a = []
b = []
c = a
a.append(1)
b.append(2)
c.append(3)
print a
print b
print c
Run Code Online (Sandbox Code Playgroud)

它将打印:

[1, 3]
[2]
[1, 3]
Run Code Online (Sandbox Code Playgroud)

你能说出原因吗?