Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Semantics of 'x = y = z' assignment in Python [duplicate]

Tags:

python

I had the following line in a loop occurring during the initialization of a singly linked list class:

previous = previous.pointer = Node(item, None)

The intended semantics was what I can obtain with:

previous.pointer = Node(item, None)
previous = previous.pointer

What I found out using pdb is that previous gets reassigned to the new Node object. And the (former) previous's pointer attribute is unchanged.

I couldn't find documentation about the expected behaviour of this kind of assignment.

like image 415
Kevin Hummerwood Avatar asked Nov 28 '15 01:11

Kevin Hummerwood


People also ask

Does Python copy on assignment?

Assignment statements in Python do not copy objects, they create bindings between a target and an object. For collections that are mutable or contain mutable items, a copy is sometimes needed so one can change one copy without changing the other.

Is assignment an expression in Python?

Assignment expressions were added to Python in version 3.8. The general idea is that an assignment expression allows you to assign to variables within an expression. This operator has been called the "walrus operator", although their real name is "assignment expression".

What is assignment in Python?

An assignment statement evaluates the expression list (remember that this can be a single expression or a comma-separated list, the latter yielding a tuple) and assigns the single resulting object to each of the target lists, from left to right.

How does simultaneous assignment work in Python?

The code demonstrates that simultaneous assignment really is simultaneous. The value for a does not change before the value of b , so b gets the original value of a , and we can switch the values without using an interim step of creating a temporary (and otherwise useless) variable.


1 Answers

This is well explained in the documentation:

An assignment statement evaluates the expression list (remember that this can be a single expression or a comma-separated list, the latter yielding a tuple) and assigns the single resulting object to each of the target lists, from left to right.

(emphasis mine)

Where the term target_list is used in the grammar as follows:

assignment_stmt ::=  (target_list "=")+ (expression_list | yield_expression)

(Note the + sign after the first parenthesis - this allows chain assignments)

Thus, the resulting semantics:

target_list1 = target_list2 = expression

is equivalent to:

target_list1 = expression
target_list2 = expression

There is no way of confusing what is being assigned (evaluates the expression list) with what is the target of the assignment, because assignment is a statement, not an expression. Hence, all with = in it, will not be treated as an expression - only the right most part. Next, all assignment statements will be processed left to right (i.e. their target lists will have the expression's value assigned).

like image 115
BartoszKP Avatar answered Oct 22 '22 17:10

BartoszKP