Reputation: 157
For a list of integers, such as A = [2, 10, -5]
, I get the error
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
Code:
for i, v in enumerate(A):
while 1<=v<=len(A) and v != A[v-1]:
v, A[v-1] = A[v-1], v
but this works:
for i, v in enumerate(A):
while 1<=v<=len(A) and v != A[v-1]:
A[v-1], v = v, A[v-1]
Why the order of the swapping elements matters here? v
is always being checked to be in bound.
Weirdly enough cannot reproduce a smaller example. But,
A = [6, 5, 4, 3, 2]
becomes an infinite loop.
Upvotes: 2
Views: 184
Reputation: 11753
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
You need to try running out your algorithm in your head:
Start:
i = 0, v = 6
v(6) is not between 1 and 5: next iteration
i = 1, v = 5, A[5-1] = 2
5 is between 1 and 5; v is not equal to 2: swap -> v = 2; A[4] = 2
i = 1, v = 2, A[2-1] = 5
2 is between 1 and 5; v is not equal to 5: swap -> v = 5; A[1] = 5
i = 1, v = 5, A[5-1] = 2
5 is between 1 and 5; v is not equal to 2: swap -> v = 2; A[4] = 2
i = 1, v = 2, A[2-1] = 5
2 is between 1 and 5; v is not equal to 5: swap -> v = 5; A[1] = 5
... and on and on
I don't think your algorithm makes sense. It's unclear why you are using the values in your list to index the list during your loop. I think this confusion about the index and values is at the root of your problem.
Upvotes: 0
Reputation: 77867
I reproduced this with [2, 10, -5]. The detailed sequence of operations is
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.
If you switch the assignment order:
A[v-1], v = 2, 10
# This assignment breaks into ...
A[2-1] = 2
v = 10
In this case, your while
conditions have properly guarded a legal assignment.
Note that you are not swapping list values; v
is a local variable; it is not a reference to A[i]. For instance, in the above example, you do get v=10
, but this does not affect the value of A[0].
Upvotes: 2
Reputation: 2843
Python swaps the variables in the order provided, so v
is assigned the value at A[v-1]
, and then tries to reassign A[v-1]
- but since v has been modified to be a list element, v-1
is out of range of A
.
Upvotes: 7