a = [1, 2, 3]
a[-1] += a.pop()
This results in [1, 6]
.
a = [1, 2, 3]
a[0] += a.pop()
This results in
Using a thin wrapper around a list with debugging print-statements can be used to show the order of evaluation in your cases:
class Test(object):
def __init__(self, lst):
self.lst = lst
def __getitem__(self, item):
print('in getitem', self.lst, item)
return self.lst[item]
def __setitem__(self, item, value):
print('in setitem', self.lst, item, value)
self.lst[item] = value
def pop(self):
item = self.lst.pop()
print('in pop, returning', item)
return item
When I now run your example:
>>> a = Test([1, 2, 3])
>>> a[-1] += a.pop()
in getitem [1, 2, 3] -1
in pop, returning 3
in setitem [1, 2] -1 6
So it starts by getting the last item, which is 3, then pops the last item which is also 3, adds them and overwrites the last item of your list with 6
. So the final list will be [1, 6]
.
And in your second case:
>>> a = Test([1, 2, 3])
>>> a[0] += a.pop()
in getitem [1, 2, 3] 0
in pop, returning 3
in setitem [1, 2] 0 4
This now takes the first item (1
) adds it to the popped value (3
) and overwrites the first item with the sum: [4, 2]
.
The general order of evaluation is already explained by @Fallen and @tobias_k. This answer just supplements the general principle mentioned there.