# python – What does it mean that x is evaluated only once in a cumulative assignment statement such as x + = 1?

## Question: Question:

I understand the meaning of the in-place operation in the second half, but I don't understand the meaning that x is evaluated only once.
Regarding the value, I think that either method is the same as evaluating the initial value of x and x + 1.

Cumulative assignment expressions such as x += 1 can be rewritten as x = x + 1 to behave in much the same way, but they are not exactly equivalent. For cumulative assignments, x is evaluated only once. Also, as a matter of fact, he will perform an in-place operation if possible. This means that instead of creating a new object and assigning it to the target at the time of assignment, it modifies the contents of the previous object.

An augmented assignment expression like x + = 1 can be rewritten as x = x + 1 to achieve a similar, but not exactly equal effect. In the augmented version, x is only evaluated once. Also, when possible, the actual operation is performed in-place, meaning that rather than creating a new object and assigning that to the target, the old object is modified instead.

## int calculation

Since the calculation time did not change in either case, it was omitted.

Next is the version that adds elements to the list.

## List (accumulation)

augmentassign.py

Time taken for calculation: 0.0144632940292358398 [sec]

import time
firstTime = time.time()
i=0
list1=[1,1,1]
while i <100_000:
i+=1
list1 +=[1]

usedTime = time.time() - firstTime
print ("計算にかかった時間:{0}".format(usedTime) + "[sec]")

## List (normal)

normalassign.py

Time taken for calculation: 25.47399997711816 [sec]

import time
firstTime = time.time()
i=0
list1=[1,1,1]
while i <100_000:
i+=1
list1=list1+[1]

usedTime = time.time() - firstTime
print ("計算にかかった時間:{0}".format(usedTime) + "[sec]")

It seems that this is an overwhelming difference depending on whether it is simply in-place or not.

## Tuple

It was omitted because the calculation time did not change in either case by simply adding an element. Is it because both are out-place?

Now, let's increase the amount of calculation of the original operand itself.
Just in case, I put a confirmation that the id of list has not changed.

## List with calculated elements in the operand (normal type)

evalOnLeft_normal.py

Id before calculation: 140108440645824
list1: [1000001, 1000001, 1000001, 1000001, 1000001, 1000001, 1000001, 1000001, 1000001, 1000001]
Calculated id: 140108440645824
Time taken for calculation: 3.2987570762634277 [sec]

import time

firstTime = time.time()
i=0
list1=[1,1,1,1,1,1,1,1,1,1]
print("計算前のid:{0}".format(id(list1)))

def evalOnLeft():
global i
whichIndex=i%10
return whichIndex

while i <10_000_000:

list1[evalOnLeft()]=list1[evalOnLeft()]+1
i+=1

usedTime = time.time() - firstTime
print("list1:{0}".format(list1))
print("計算後のid:{0}".format(id(list1)))
print("計算にかかった時間:{0}".format(usedTime) + "[sec]")

## List with calculated elements in the operand (cumulative type)

evalOnLeft_augment.py

Id before calculation: 140579620745408
list1: [1000001, 1000001, 1000001, 1000001, 1000001, 1000001, 1000001, 1000001, 1000001, 1000001]
Calculated id: 140579620745408
Time taken for calculation: 2.5201609134674072 [sec]

import time

firstTime = time.time()
i=0
list1=[1,1,1,1,1,1,1,1,1,1]
print("計算前のid:{0}".format(id(list1)))

def evalOnLeft():
global i
whichIndex=i%10
return whichIndex

while i <10_000_000:

list1[evalOnLeft()]+=1
i+=1

usedTime = time.time() - firstTime
print("list1:{0}".format(list1))
print("計算後のid:{0}".format(id(list1)))
print("計算にかかった時間:{0}".format(usedTime) + "[sec]")

So, there was a plausible time difference.
As the amount of computation of the operands themselves increases, it may be worth worrying about.

After that, it may be a definition of the word whether the "number of evaluations" is different between the cumulative type and the normal type, or what was the intention of the creator of the doc.

For " x is evaluated only once", it is easier to interpret it as representing anything that can come to the left side of the cumulative assignment statement, rather than literally understanding x as an identifier. it might be.

i = 0
def inc():
global i
i += 1
return i
list = [1, 2, 3]
list[inc()] += 1
print(list) //->[1, 3, 3]

In such an example, you can clearly see the difference between list[inc()] += 1 and list[inc()] = list[inc()] + 1 .

Scroll to Top