Loading...

Python置换操作浅析(a, b=b, a)【Python】

在C/C++中,交换两个数的常规方法有以下两种:

  1. 借助临时变量
    tmp = a a = b b = tmp 
  2. 加法操作
    a = a + b b = a - b a = a - b 

但是在Python中,还有一种更简便的方法:

a, b = b, a # 或 b, a = a, b 

这种方法在一般情况下可以很容易的完成变量交换,甚至在数组中一般情况也是成立的。但是这两天在刷Leetcode时, 题目:缺失的第一个正数,碰到了一个问题,在对数组中的两个值进行交换的时候,即将nums[i]nums[nums[i]-1]交换时,下面的两个语句,只有第二个语句是正确的:

nums[i], nums[nums[i] - 1] = nums[nums[i] - 1], nums[i] nums[nums[i] - 1], nums[i] = nums[i], nums[nums[i] - 1] 

究其原因,明白了置换操作的原理就可以很容易理解。

我们通过查看置换前后变量a,b的地址去理解,看下面的例子:

a,b = 1,2 print("-----置换前------") print(a,b) print("a的地址:", id(a)) print("b的地址:", id(b)) a,b = b,a print("-----置换后------") print(a,b) print("a的地址:", id(a)) print("b的地址:", id(b)) 

输出结果是

-----置换前------ 1 2 a的地址: 4444362368 b的地址: 4444362400 -----置换后------ 2 1 a的地址: 4444362400 b的地址: 4444362368 

可以看到,python中对变量的赋值是改变变量的指向,将变量指向目标值的地址。

所以,对于置换操作a, b = b, a,操作顺序是先计算得到等号右边的所有数值,再将值依次赋给等号的左边。

再回到上面出问题的例子
错误的:

nums[i], nums[nums[i] - 1] = nums[nums[i] - 1], nums[i] 

正确的:

nums[nums[i] - 1], nums[i] = nums[i], nums[nums[i] - 1] 

问题就出在计算得到等式右边后,将值「依次」赋给等号的左边。可以看到nums[nums[i] - 1]引用了nums[i]。具体来说,对于错误的,由于nums[nums[i] - 1]引用了nums[i],而这时的nums[i]已经重新赋值完毕,所以不正确。

总结一下,对于置换操作a, b = b, a,原理是计算得到等式右边后,将值「依次」赋给等号的左边。然后如果ab存在引用关系,特别是在数组中,特别注意后者不能引用前者。