3

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)

2
  • result *= nim - 3 is equivalent to result = result * (num - 3) Commented Dec 27, 2022 at 20:04
  • 1
    If the operations were applied with - last, then first you'd do result *= num, and then you'd subtract 3 from that but not assign it to anything (because there's no assignment implied by the - operator). That would obviously be nonsensical, which is why it doesn't work like that. Instead the entire RHS of the *= gets evaluated together, as if you'd put parens around it, before the multiplication and assignment happens. Commented Dec 27, 2022 at 20:06

4 Answers 4

1

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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)

Comments

0
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)

Comments

0

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)

1 Comment

While the parentheses may aid reading the code and understanding order of operations, they are unnecessary in result_2 = (result_2 * number) -3

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.