在Python中迭代交换元素

在Python中迭代交换元素,python,python-3.x,Python,Python 3.x,对于这个简单的代码片段,我很难理解幕后发生了什么: def changeArray(arr): for i in range(len(arr)): arr[i], arr[arr[i] - 1] = arr[arr[i] - 1], arr[i] print(arr) return(arr) 该代码假定数组的元素为1到n之间的整数。 当输入为[1,3,4,2]时,给定代码的输出为: [1, 3, 4, 2] [1, 4, 4, 3] [1

对于这个简单的代码片段,我很难理解幕后发生了什么:

def changeArray(arr):
     for i in range(len(arr)):
         arr[i], arr[arr[i] - 1] = arr[arr[i] - 1], arr[i]
         print(arr)
     return(arr)
该代码假定数组的元素为1到n之间的整数。 当输入为[1,3,4,2]时,给定代码的输出为:

[1, 3, 4, 2]
[1, 4, 4, 3]
[1, 4, 4, 3]
[1, 4, 4, 3]
Out[8]: [1, 4, 4, 3]
当我期待它打印并返回此文件时:

[1, 3, 4, 2]
[1, 4, 3, 2]
[1, 4, 3, 2]
[1, 2, 3, 4]
Out[8]: [1, 2, 3, 4]
当代码只交换元素时,为什么值会发生变化


编辑:

事实证明,更改交换顺序可以解决问题:

def changeArray(arr):
     for i in range(len(arr)):
         arr[arr[i]-1], arr[i] = arr[i], arr[arr[i]-1]
         print(arr)
     return(arr)
这将提供以下输出:

[1, 3, 4, 2]
[1, 4, 3, 2]
[1, 4, 3, 2]
[1, 2, 3, 4]
Out[8]: [1, 2, 3, 4]

更改顺序是如何按预期进行交换的,而相反的操作完全是另一回事?

将表达式更改为

 arr[arr[i] - 1], arr[i] = arr[i], arr[arr[i] - 1]

他为我工作。仍然不知道这些值是如何或为什么变化的。很抱歉,我对python也是新手。

一般来说,您不应该使用正在变异的对象来指定要替换的目标位置,否则它会变得非常混乱

当你写这篇文章时:

 arr[i], arr[arr[i] - 1] = arr[arr[i] - 1], arr[i]
这大致相当于:

tup = arr[arr[i] - 1], arr[i]
x, y = tup
arr.__setitem__(i, x)
arr.__setitem__(arr[i] - 1, y)
(关于如何翻译这篇文章的全部细节都很详细,但希望直观的想法简单得多。)

这应该清楚地说明为什么你会得到你想要的结果。以及为什么下面所有这些都是你想要的:

x = arr[i] - 1
arr[i], arr[x] = arr[x], arr[i]

arr[arr[i] - 1], arr[i] = arr[i], arr[arr[i] - 1]

def swap(x, y):
    arr[x], arr[y] = arr[y], arr[x]
swap(i, arr[i] - 1)

我认为第一个是最简单的(第二个看起来很简单,但这只是误导性的)。

我想你可能想要
arr[I-1]
而不是
arr[arr[I]-1]
@damores arr[arr[I]-1]将第I个索引中的元素交换到一个新索引ind,这样新索引将满足arr[ind]=ind+1。我的推理正确吗?
arr[arr[I]-1]
将等于
arr[I]-1
的索引带入
arr
。这意味着您交换的元素的索引取决于
arr
arr[i]-1
th元素的值。您不希望出现这种情况-您交换的元素位置与元素的值无关。您是否希望此代码适用于包含较大元素的列表,例如
[11,12,13,14]
?哦,不。我提到了一个假设,即数组中的所有元素都来自[1,n]其中n是数组的长度,它使索引超出范围。