对于整数列表,例如A = [2, 10, -5]
,我得到了错误
Traceback (most recent call last):
File "so.py", line 6, in <module>
v, A[v-1] = A[v-1], v
IndexError: list assignment index out of range
代码:
for i, v in enumerate(A):
while 1<=v<=len(A) and v != A[v-1]:
v, A[v-1] = A[v-1], v
但这可行:
for i, v in enumerate(A):
while 1<=v<=len(A) and v != A[v-1]:
A[v-1], v = v, A[v-1]
为什么交换元素的顺序在这里很重要?始终会检查v
是否处于绑定状态。
足够奇怪的是无法重现一个较小的示例。但,
A = [6, 5, 4, 3, 2]
变成无限循环。
答案 0 :(得分:7)
Python按照提供的顺序交换变量,因此v
被分配了A[v-1]
的值,然后尝试重新分配A[v-1]
-但由于v已被修改为列表元素v-1
超出了A
的范围。
答案 1 :(得分:2)
我用[2,10,-5]复制了此内容。 详细的操作顺序是
i, v = 0, 2
1 <= 2 ? OK
2 != A[1] ? OK ... stay in loop
v, A[v-1] = 10, 2
# This assignment breaks into ...
v = 10
A[10-1] = 2
# ... and this second assignment is out of range.
如果您切换分配顺序:
A[v-1], v = 2, 10
# This assignment breaks into ...
A[2-1] = 2
v = 10
在这种情况下,您的while
条件已经妥善保护了法律转让。
请注意,您不是交换列表值; v
是局部变量;它不是对A [i]的引用。例如,在上面的示例中,您确实获得了v=10
,但这确实不会影响A [0]的值。
答案 2 :(得分:0)
A = [6, 5, 4, 3, 2]
for i, v in enumerate(A):
while 1<=v<=len(A) and v != A[v-1]:
v, A[v-1] = A[v-1], v
您需要尝试用尽您的算法:
开始:
i = 0,v = 6
v(6)不在1到5之间:下一次迭代
i = 1,v = 5,A [5-1] = 2
5在1到5之间; v不等于2:swap-> v = 2; A [4] = 2
i = 1,v = 2,A [2-1] = 5
2在1到5之间; v不等于5:swap-> v = 5; A [1] = 5
i = 1,v = 5,A [5-1] = 2
5在1到5之间; v不等于2:swap-> v = 2; A [4] = 2
i = 1,v = 2,A [2-1] = 5
2在1到5之间; v不等于5:swap-> v = 5; A [1] = 5
...以及不断的
我认为您的算法没有道理。目前尚不清楚为什么要在循环中使用列表中的值来索引列表。我认为对索引和值的这种混淆是您问题的根源。