我刚刚意识到pythonic交换并不总是有效。
def swap(x,y):
x,y = y,x
a = 1
b = 2
swap(a,b)
print b
结果:2
为什么交换变量的pythonic方式在这种情况下不起作用?我需要临时变量吗?
答案 0 :(得分:4)
在函数定义的第一行
def swap(x,y):
x
和y
是所谓的形式参数。
当你打电话
swap(a, b)
您正在传递a
和b
作为实际参数。
现在发生的事情是Python为你传递的实际参数创建新名称。
函数体x
内部现在是内存中整数对象的新名称,其名称为a
。 y
现在是内存中整数对象的新名称,名称为b
。这就是为什么Python既不是按值调用也不是按引用调用,但最好描述为call-by-assignment。
与流行的看法相反,调用函数和赋值对于可变和不可变参数的工作方式完全相同。您将看到您为可变值观察到的相同行为:
>>> def swap(x,y):
... x,y = y,x
...
>>> a = [1]
>>> b = [2]
>>> swap(a,b)
>>> a
[1]
>>> b
[2]
因此,一旦您了解了分配如何在Python中工作,您还将了解函数调用的工作原理。
举一个例子:如果你没有写一个函数,你的代码就等同于:
a = 1
b = 2
x = a
y = b
x,y = y,x
del x
del y
在第3行中,您将为整数对象创建一个新名称x
,该名称也是名称a
。第4行遵循相同的逻辑。
在第5行中,您要创建右侧的值为(y, x)
的元组(2, 1)
,然后将其解压缩,即名称x
重新分配< / em>到值2,名称y
被重新分配给值1:
>>> a = 1
>>> b = 2
>>> x = a
>>> y = b
>>> x,y = y,x
>>> x
2
>>> y
1
这里要注意的重要一点是,a
和b
从未停止过分别为值1和2的名称:
>>> a
1
>>> b
2
最后两行只取消绑定名称x
和y
,这大致等同于退出其范围后函数中发生的事件。请注意,取消绑定a
和b
后,名称x
和y
仍会受到约束。
>>> a
1
>>> b
2
答案 1 :(得分:1)
您从未返回并分配了结果。否则,正如Joran所说,你只是在函数中创建局部变量。例如:
def swap(a, b):
print "swap called"
return (b,a)
a = 1
b = 2
print a,b
a,b = swap(a,b)
print a,b
显示以下结果:
1 2 swap called 2 1
答案 2 :(得分:1)
您需要退货;交换的变量