Consider this code?
b = [[5], [3]]
a = b[1]
b[-1] += b.pop()
print(a)
This gives [3,3]
.
You can't explain it by expanding b[-1] += b.pop()
to b[-1] = b[-1] + b.pop()
it seems.
Why do you get this output?
Consider this code?
b = [[5], [3]]
a = b[1]
b[-1] += b.pop()
print(a)
This gives [3,3]
.
You can't explain it by expanding b[-1] += b.pop()
to b[-1] = b[-1] + b.pop()
it seems.
Why do you get this output?
Because if you work with b[-1]
the reference to the second list is only fetched once, next the operation +=
is done and finally it is stored back into the list. So b[-1] += b.pop()
is basically equivalent to:
tmp = b[-1] # tmp = [3]
tmp += b.pop() # tmp = [3,3], b = [[5]]
b[-1] = tmp # tmp = [3,3], b = [[3,3]]
(but of course there is tmp
, the above fragment is done at interpreter level)
Now tmp
is a refence to the second list in b
(so tmp is a
). So this means that you extend inplace a
with b.pop()
. b.pop()
is [3]
. So what you do is you extend tmp
(which is [3]
at that moment) with tmp
. And so tmp
(and thus a
becomes [3,3]
). So b
is now [[3,3]]
.
Mind that x += y
for list
s is not equivalent to x = x+y
. Indeed, if you write code like:
>>> a = [1]
>>> b = a
>>> b = b + [2]
>>> print(a,b)
[1] [1, 2]
this will not update a
(since it is not done inplace). Whereas for:
>>> a = [1]
>>> b = a
>>> b += [2]
>>> print(a,b)
[1, 2] [1, 2]
will result in a
and b
being both [1,2]
. Of course, usually +=
is supposed to behave like adding, but the adding is done inplace which can have some effects.
Try printing b[-1] right before you print a. b[-1] refers to the last element in b, which you are adding another element to. It appears that this happens because when you do a = b[1]
, it must be assigned by reference since a is updated when b[1] (same as b[-1] in this case) is updated.
First there are only 2 elements in the list b.
b = [[5], [3]]
a = b[1]
print b[1]
# gives [3]
print b[-1]
# also gives [3] because here -1 refers to the last element and there are
# only two elements.
b[-1] += b.pop()
# here you are appending 3 to [3] of b
print b[-1]
print a
# that is why when you print a it gives [3,3] as the b[1] value was
# appended to a in the second step itself and you are just printing here.
Hope you got what I am trying to say..