1

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?

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
Simd
  • 19,447
  • 42
  • 136
  • 271

3 Answers3

6

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 lists 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.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
0

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.

Dylan Hamilton
  • 662
  • 4
  • 14
0

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..

Schmuddi
  • 1,995
  • 21
  • 35
sk79
  • 35
  • 10