Python迭代交换数组元素的代码执行逻辑困惑
解析Python数组交换代码的底层执行逻辑
嘿,我来帮你把这段代码的执行过程拆解得明明白白,搞清楚为什么输入[1,3,4,2]会得到[1,4,4,3]这个结果~
首先得明确代码的前提:题目假设数组元素是1到n的整数,所以每个元素arr[i]-1都是合法的数组索引(毕竟数组索引从0开始)。而这段代码的“坑”就藏在Python赋值语句的执行顺序里——左边的赋值是按顺序执行的,第一个赋值会改变数组元素,进而影响第二个赋值的索引计算,而不是像很多人想的那样“同时交换”。
我们一步步模拟输入arr = [1,3,4,2]时的循环过程:
第一次循环:i=0
当前数组:[1,3,4,2]
执行交换语句arr[0], arr[arr[0]-1] = arr[arr[0]-1], arr[0]:
- 先计算右侧的值:
arr[arr[0]-1] = arr[1-1] = arr[0] =1,arr[0] =1,所以右侧是(1,1) - 左侧依次赋值:
arr[0] =1(没变化),接着arr[0] =1(还是没变化)
数组保持[1,3,4,2],print输出:[1, 3, 4, 2]
第二次循环:i=1
当前数组:[1,3,4,2]
执行交换语句:
- 先计算右侧的值:
arr[arr[1]-1] = arr[3-1] = arr[2] =4,arr[1] =3,右侧是(4,3) - 左侧开始赋值:
- 先给
arr[1]赋值4,数组变成[1,4,4,2] - 再计算第二个赋值的索引:此时
arr[1]已经是4了,所以arr[1]-1 =4-1=3,给arr[3]赋值3,数组变成[1,4,4,3]
print输出:[1, 4, 4, 3]
- 先给
第三次循环:i=2
当前数组:[1,4,4,3]
执行交换语句:
- 先计算右侧的值:
arr[arr[2]-1] = arr[4-1] = arr[3] =3,arr[2] =4,右侧是(3,4) - 左侧依次赋值:
- 给
arr[2]赋值3,数组变成[1,4,3,3] - 计算第二个索引:此时
arr[2]是3,3-1=2,给arr[2]赋值4,数组又变回[1,4,4,3]
print输出:[1, 4, 4, 3]
- 给
第四次循环:i=3
当前数组:[1,4,4,3]
执行交换语句:
- 先计算右侧的值:
arr[arr[3]-1] = arr[3-1] = arr[2] =4,arr[3] =3,右侧是(4,3) - 左侧依次赋值:
- 给
arr[3]赋值4,数组变成[1,4,4,4] - 计算第二个索引:此时
arr[3]是4,4-1=3,给arr[3]赋值3,数组变回[1,4,4,3]
print输出:[1, 4, 4, 3]
- 给
循环结束后,函数返回[1,4,4,3],这就是你看到的结果。
为什么和你的预期不符?
你可能误以为交换是“同时”完成的,也就是两个索引都用循环开始时的arr[i]值。但Python的赋值语句是先计算右侧所有值,再按顺序给左侧变量/元素赋值——第一个赋值会改变数组元素,导致第二个赋值的索引计算用了更新后的值,这就产生了和预期不同的结果。
如果想实现“把每个元素放到对应位置(即arr[i] = i+1)”的正确置换,可以先保存原始的arr[i]值,避免后续修改影响索引计算,比如:
def changeArray(arr): for i in range(len(arr)): val = arr[i] if val != i + 1: # 已经在正确位置就跳过 arr[i], arr[val - 1] = arr[val - 1], arr[i] print(arr) return arr
输入[1,3,4,2]时,这段代码会输出并返回[1,2,3,4],符合常规的置换预期。
内容的提问来源于stack exchange,提问作者dexteran
相关产品推荐
相关产品推荐

