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存在引用关系,特别是在数组中,特别注意后者不能引用前者。

你可能感兴趣的:(python,python)