Home > Back-end >  Order of operations Python
Order of operations Python

Time:12-28

The order of operations in my code seems off...

numbers=[7, 6, 4]
result = 1
for num in numbers:
        result *= num - 3
        print(result)

In this code, I would expect the following to occur...

result=1
result = 1 * 7 - 3 = 7 - 3 = 4
result = 4 * 6 - 3 = 24 - 3 = 21
result = 21 * 4 - 3 = 84 - 3 = 81

HOWEVER, running the program outputs

result = 1

result = 1 * 7 - 3 = 1 * 4 = 4

result = 4 * 6 - 3 = 4 * 3 = 12

result = 12 * 4 - 3 = 12 * 1 = 12

Why with the *= operator is the order of operations altered? 
My understanding is it does not have any special properties it merely saves space instead of writing: 
result = result * num - 3 
we get
result *= num - 3

and for some reason..  (result = result * num - 3) != (result *= num - 3)

CodePudding user response:

Why with the *= operator is the order of operations altered?

The *= is not an operator, it's delimiter. Check the '2. Lexical analysis' of 'The Python Language Reference':

The following tokens are operators:

        -       *       **      /       //      %      @
<<      >>      &       |       ^       ~       :=
<       >       <=      >=      ==      !=

The following tokens serve as delimiters in the grammar:

(       )       [       ]       {       }
,       :       .       ;       @       =       ->
 =      -=      *=      /=      //=     %=      @=
&=      |=      ^=      >>=     <<=     **=

The period can also occur in floating-point and imaginary literals. A sequence of three periods has a special meaning as an ellipsis literal. The second half of the list, the augmented assignment operators, serve lexically as delimiters, but also perform an operation.

Moreover, in your code you have the, augmented assignment statement, as per '7.2.1. Augmented assignment statements':

Augmented assignment is the combination, in a single statement, of a binary operation and an assignment statement:

[...]

An augmented assignment evaluates the target (which, unlike normal assignment statements, cannot be an unpacking) and the expression list, performs the binary operation specific to the type of assignment on the two operands, and assigns the result to the original target. The target is only evaluated once.

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.

Unlike normal assignments, augmented assignments evaluate the left-hand side before evaluating the right-hand side. For example, a[i] = f(x) first looks-up a[i], then it evaluates f(x) and performs the addition, and lastly, it writes the result back to a[i].

The '6.16. Evaluation order' says:

Python evaluates expressions from left to right. Notice that while evaluating an assignment, the right-hand side is evaluated before the left-hand side.

You can also check the '6.17. Operator precedence' chapter, but it's not about the statements.

CodePudding user response:

The expression on the right hand side of the *= is evaluated first.

7 - 3 => 4 which multiplied by 1 is 4.

6 - 3 => 3 which multiplied by 4 is 12.

4 - 3 => 1 which multiplied by 12 is 12.

To achieve what you are expecting:

numbers = [7, 6, 4]
result = 1
for num in numbers:
    result = result * num - 3
    print(result)

CodePudding user response:

numbers=[7, 6, 4] 
result = 1 
for num in numbers: 
    result *= num-3   
print(result)

The *= operator is a compound assignment operator, which means that it combines the assignment operator = with another operator https://www.educative.io/answers/what-are-the-compound-assignment-identity-operators-in-python

numbers=[7, 6, 4] 
result = 1 
for num in numbers: 
    result = result*num-3
    print(result)

CodePudding user response:

the *= means that the * will be used between what's before it and what's after so you need to get result_2 in this example to get what you want :

numbers = [7,6,4]
result = 1 
result_2 = 1 
for number in numbers:
    result *= number -3 
    result_2  = result_2 * number -3
    print(result, result_2)
  • Related