Python Tuple Assignment Involving List Index Failed
Solution 1:
A good explanation of what is happening under the hood can be found here. Essentially when you have multiple assignments anything to the right of the =
will be fully evaluated first.
Let’s take your first example and walk through what is happening.
s[s[0]], s[0] = s[0], s[s[0]] # s == [2, 1]
This is equivalent to the following where temp values store the evaluated right hand sides
# assigns right hand side to temp variables
temp1 = s[0] # 1
temp2 = s[s[0]] # 2# then assign those temp variables to the left-hand side
s[s[0]] = temp1 # s[1] = 1 —-> s= [1, 1]
s[0] = temp2 # s[0] = 2 —-> s = [2, 1]
In the case you get an index error the following happens...
# assigns right hand side to temp variables
temp1 = s[s[0]] # 2
temp2 = s[0] # 1# then assign those temp variables to the left-hand side
s[0] = temp1 # s[0] = 2 —-> s= [2, 1]
s[s[0]] = temp2 # s[2] -> Index error (highest index of s is 1)
Solution 2:
When you do s[a], s[b] = s[b], s[a]
, the right side of the =
is evaluated completely before assigning the values back to the list, which is why one-line-swaps work in Python. However, it seems like the left side of the =
is not evaluated all at once, but one after another. Thus, for s[0], s[s[0]] = s[s[0]], s[0]
, the s[0]
in s[s[0]]
on the left side is evaluated after s[0]
was assigned a new value.
This can be verified by wrapping the indices into a function that prints them before returning them:
>>> s = [1, 2]
>>> f = lambda i, j: print("get", i, j) or j
>>> s[f("a",0)], s[f("b",s[f("c",0)])] = s[f("d", s[f("e", 0)])], s[f("f", 0)]
get e 0get d 1get f 0get a 0get c 0get b 2<-- updated to 2 before s[0] was evaluated
Traceback (most recent calllast):
File "<stdin>", line 1, in<module>
IndexError: list assignment index outofrange
In other words, the expression s[0], s[s[0]] = s[s[0]], s[0]
seems to be roughly equivalent to the following, i.e. the indices used in the LHS are not evaluated all at once before being assigned new values:
tmp = (s[s[0]], s[0])
s[0] = tmp[0]
s[s[0]] = tmp[1]
Solution 3:
lists are assigned by reference, meaning changing the content of the source will result in changing the target assignment.
list = [1,2]
a = [4]
list.append(a) # value is 4
a[0] = 5 # also changes target "list"
print (list) # will output [1,2,[5]]
Post a Comment for "Python Tuple Assignment Involving List Index Failed"