python列表原地交换nums[i], nums[nums[i]] = nums[nums[i]], nums[i]的解决方法

问题描述

python列表原地交换问题,当索引为 数组[索引] 的表达形式时,不合适的交换操作将导致错误的输出

  1. 法1(错误)
nums[i], nums[nums[i]] = nums[nums[i]], nums[i]
  1. 法2(正确)
nums[nums[i]], nums[i] = nums[i], nums[nums[i]]

测试

# 法1
nums1 = [3,3,2,2,1,1]
i = 0
nums1[i], nums1[nums1[i]] = nums1[nums1[i]], nums1[i]
print(nums1)

# 法2
nums2 = [3,3,2,2,1,1]
i = 0
nums2[nums2[i]], nums2[i] = nums2[i], nums2[nums2[i]]
print(nums2)
执行完成,耗时:44 ms
[2, 3, 3, 2, 1, 1]
[2, 3, 2, 3, 1, 1]

原因

执行nums1[i], nums1[nums1[i]] = nums1[nums1[i]], nums1[i]时,python中会将左右分别形成元组,再按照先左后右的原则进行赋值,所以,不妨设 ( a , b ) = ( c , d ) (a, b) = (c, d) (a,b)=(c,d),过程为 a = c , b = d a = c, b = d a=c,b=d,所以这里将 n u m s 1 [ i ] = n u m s 1 [ n u m s 1 [ i ] ] nums1[i] = nums1[nums1[i]] nums1[i]=nums1[nums1[i]] 时,已经更改了 n u m s [ i ] nums[i] nums[i] 的值,再进行 n u m s 1 [ n u m s 1 [ i ] ] = n u m s 1 [ i ] nums1[nums1[i]] = nums1[i] nums1[nums1[i]]=nums1[i] 时,等式左边索引发生改变,故发生错误。

具体来说, i = 0 i = 0 i=0,先执行 n u m s 1 [ 0 ] = n u m s 1 [ n u m s 1 [ 0 ] ] nums1[0] = nums1[nums1[0]] nums1[0]=nums1[nums1[0]],于是
n u m s 1 [ n u m s 1 [ 0 ] ] = n u m s 1 [ 3 ] = 2 nums1[nums1[0]] = nums1[3] = 2 nums1[nums1[0]]=nums1[3]=2 n u m s 1 [ 0 ] = 2 nums1[0] = 2 nums1[0]=2
再执行 n u m s 1 [ n u m s 1 [ 0 ] ] = n u m s 1 [ 0 ] nums1[nums1[0]] = nums1[0] nums1[nums1[0]]=nums1[0] 时,等式右边先计算,再将值复制给左边,有:
n u m s 1 [ 0 ] = 2 nums1[0] = 2 nums1[0]=2 n u m s 1 [ n u m s 1 [ 0 ] ] = n u m s 1 [ 2 ] = 2 nums1[nums1[0]] = nums1[2] = 2 nums1[nums1[0]]=nums1[2]=2

于是,第二步修改了nums1[2]的值,并没有修改nums1[3]的值,结果为 [2, 3, 3, 2, 1, 1]

思考

对于正确的方式,在此不再详细分析

猜你喜欢

转载自blog.csdn.net/qq_45510888/article/details/123440823