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.
As for the value, I think we can evaluate the initial value of x and x+1 in either way.
7.2.1. Aggregated assignment statement
A cumulative assignment expression, such as x+=1
, can be rewritten to make it look much the same as x=x+1
, but is not strictly equivalent.For cumulative substitutions, x
is evaluated only once.In addition, the actual operation is to perform an in-place operation if possible.This means changing the contents of the previous object instead of creating a new object and substituting it for the target at the time of substitution.
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.
This is additional information that takes your opinions into account.
Either way, the calculation time was not changed, so it was omitted
Next is the version to add elements to the list.
augmentassign.py
Calculation time: 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("Time spent calculating: {0}".format(usedTime)+"[sec]")
normalassign.py
Calculated time: 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("Time spent calculating: {0}".format(usedTime)+"[sec]")
There seems to be an overwhelming difference between simply in-place and in-place.
I didn't change the calculation time for either of the additional elements, so I omitted it
Maybe it's because both of them are out-place.
Then, I will try to increase the calculation of the original operand itself.
Just to be sure, I have confirmed that the id on the list has not changed.
evalOnLeft_normal.py
Pre-calculation id:140108440645824
list1: [1000001,1000001,1000001,1000001,1000001,1000001,1000001,1000001,1000001]
Calculated id: 140108440645824
Calculated time: 3.2987570762634277 [sec]
import time
firstTime = time.time()
i = 0
list1 = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ]
print("Pre-calculated id: {0}".format(id(list1))))
defaultOnLeft():
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("After Calculation id: {0}".format(id(list1))))
print("Time spent calculating: {0}".format(usedTime)+"[sec]")
evalOnLeft_augment.py
Pre-calculated id:140579620745408
list1: [1000001,1000001,1000001,1000001,1000001,1000001,1000001,1000001,1000001]
Calculated id:140579620745408
Calculated time: 2.5201609134674072 [sec]
import time
firstTime = time.time()
i = 0
list1 = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ]
print("Pre-calculated id: {0}".format(id(list1))))
defaultOnLeft():
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("After Calculation id: {0}".format(id(list1))))
print("Time spent calculating: {0}".format(usedTime)+"[sec]")
So there was a plausible time difference.
If the operands themselves are calculated more, it may be worth worrying about.
The rest may be the definition of a word that defines whether the number of evaluations is different between the cumulative and normal types, or the actual intention of the doc creator.
python python3
Wouldn't it be easier to interpret x
as representing anything that can come to the left of the cumulative assignment rather than literally understanding x
as a single identifier?
i=0
definc():
global i
i+=1
returni
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
.
I think it's a comparison with a substitute.
"If x=x+1
, evaluate x
on the right and x
on the left, but x+=1
only once, so it is not strictly equivalent (internal processing)."
I think it means the degree.
What does it mean to say that x is evaluated only once in an accumulated substitution sentence such as x+=1?
"I interpreted ""subsidiary"" as being counted in the evaluation."
If x=x+1
Calculating x+1 -- > x (first assessment)
Assessment of -->x (second assessment) replacing results with x
If x+=1
Add 1 to x -->x Assessment
If x=x+1
Calculating x+1 -- > x (first assessment)
Assessment of -->x (second assessment) replacing results with x
If x + = 1
Add 1 to x -->x Assessment
However,
A cumulative assignment expression, such as x+=1, can be rewritten as x=x+1, but is not strictly equivalent.For the cumulative assignment, x is evaluated only once.
"I think ""x is evaluated only once for the accumulated substitution"" in is an unnecessary explanation (*)."
"Strictly unequivalent" does not occur in the ""difference in the number of evaluations"", but rather the difference in whether x is being rewritten (subscribed) or not (subscribed) in the new object you generated.
そう I thought so because I couldn't think of an example where behavior changes depending on the number of evaluations.
"For those who add up, x is evaluated only once" is suspicious.
I looked into Python Documentation and found out
x+=1 is equivalent to x=operator.iadd(x,1)
x=x+1 is equivalent to x=operator.add(x,1)
said he.
This allows you to read x's ratings in the same way, whether it's in-place or not.
Also, when I put a print statement into the properties of the class, both of them had the same number of evaluations.
Below is the source and verification results.
operator--- Standard operator in functional form
describes the following:
The operator module provides an efficient set of functions corresponding to Python's built-in operators. For example, operator.add(x,y) is equivalent to the expression x+y
According to this, x=x+1
is equivalent to x=operator.add(x,y)
.
In-place operator
describes the following:
Many operations have "in-place" versions. The following functions provide a simpler way to call such operators than the usual grammar.For example, the statement x+=y is equivalent to x=operator.iadd(x,y).In other words, z=operator.iadd(x,y) is equivalent to the compound statement z=x;z+=y.
According to this, x+=1
is equivalent to x=operator.iad(x,1)
.
[Code used for verification]
class Sample():
def__init__(self, x):
self.xx = x
@property
defx(self):
print('get x==>',self.xx)
return self.xx
@x.setter
def x (self, x):
print('set x<==',x)
self.xx = x
sample=Sample(12)
sample.x + = 1
print(sample.x)
sample.x = sample.x+1
print(sample.x)
[Results]
get x==>12
set x<==13
get x == > 13
13
get x == > 13
set x<==14
get x == > 14
14
"For those who add up, x is evaluated only once" is suspicious.
is withdrawn.
From answers and comments from dosec, OOPer, peppaa, oriri5,
A cumulative assignment expression, such as x+=1, can be rewritten as x=x+1, but is not strictly equivalent.For the cumulative assignment, x is evaluated only once.
If interpreted as having a different number of evaluations of 」x を before ++= や or ++ 」 operations, の it is understandable that xx is evaluated only once しか.
Different values for each f() called
The reason why x[f()]=x[f()]+1 and x[f()]+=1 results are different is because x[f()] evaluates differently.
If the left side x
has side effects, you will be in trouble if you don't specify a one-time evaluation
Example of c if other languages are acceptable
int*p=&array[i];
*p+++=1; // *p++=*p+++1; replaces "undefined behavior"
// I don't know if p[i] will change or p[i+1] will change if there is only one evaluation.
c++ Example
inta, debugcount;
int&func() {++ debug count;return a;}
func()+=1;// Same as above, debugcount is confirmed to increase by 1 for one evaluation
What does it mean to say that x is evaluated only once in an accumulated substitution sentence such as x+=1?
It literally means that x is evaluated only once, but I think it is intended to be the expression +=1.
Here's an example of OOper essentially the same as what he says, but different from the substitution statement.
7.2.1. Aggregated assignment statement
augmented_assignment_stmt::=ugtarget augop(expression_list|yield_expression)
target:: = identifier | attributeref | subscription | slicing
augop::="+="|"-="|"*="|"@="|"/="|"//="|"%="|"**="
| ">>="|"<="|"&="|"^="|"|="
There is a subscription in the target, and the subscript notation is also covered, so lst is used as the
lst[n]+=1
is also applicable.
6.3.2.Subscription
subscription::=primary"["expression_list"]"
If the primary is a sequence, the evaluation result of the expression list must be an integer or a slice (discussed in the following section).
In the description, you can specify an expression that returns an integer to n for the list.
That's why
lst=[1,3,5]
it=iter(range(5))
lst[next(it)]+=1#lst[0]+=1
print(lst)# [2,3,5]
If so, lst[next(it)] is evaluated only once, so lst[0]+=1 but
lst=[1,3,5]
it=iter(range(5))
lst [next(it)] = lst [next(it)] +1 #lst[1] = lst[0] +1
print(lst)#[1,2,5]
In this case, 6.16. According to the evaluation order, the right-hand lst [next(it)] is evaluated first to lst[0], and the left-hand lst[next(it) is evaluated later, so it is different from lst[1].
537 Uncaught (inpromise) Error on Electron: An object could not be cloned
548 rails db:create error: Could not find mysql2-0.5.4 in any of the sources
547 Who developed the "avformat-59.dll" that comes with FFmpeg?
710 When building Fast API+Uvicorn environment with PyInstaller, console=False results in an error
© 2024 OneMinuteCode. All rights reserved.