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]

思考

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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值