Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

":=" syntax and assignment expressions: what and why?

PEP 572 introduces assignment expressions (colloquially known as the Walrus Operator), implemented for Python 3.8. This seems like a really substantial new feature since it will allow this form of assignment within comprehensions and lambda functions.

What exactly are the syntax, semantics, and grammar specification of assignment expressions?

Why is this new (and seemingly quite radical concept) being introduced, when a similar idea in PEP 379 on "Adding an assignment expression" was rejected before?

like image 437
Chris_Rands Avatar asked May 11 '18 17:05

Chris_Rands


People also ask

What is the := in Python?

:= is actually the assignment operator. In Python this is simply = . To translate this pseudocode into Python you would need to know the data structures being referenced, and a bit more of the algorithm implementation. Some notes about psuedocode: := is the assignment operator or = in Python.

What are assignment expressions?

Assignment expressions allow variable assignments to occur inside of larger expressions. While assignment expressions are never strictly necessary to write correct Python code, they can help make existing Python code more concise.

Why can't I use an assignment in an expression in Python?

The error is a simple typo: x = 0, which assigns 0 to the variable x, was written while the comparison x == 0 is certainly what was intended.

What is an 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.


2 Answers

PEP 572 contains many of the details, especially for the first question. I'll try to summarise/quote concisely arguably some of the most important parts of the PEP:

Rationale

Allowing this form of assignment within comprehensions, such as list comprehensions, and lambda functions where traditional assignments are forbidden. This can also facilitate interactive debugging without the need for code refactoring.

Recommended use-case examples

a) Getting conditional values

for example (in Python 3):

command = input("> ") while command != "quit":     print("You entered:", command)     command = input("> ") 

can become:

while (command := input("> ")) != "quit":     print("You entered:", command) 

Similarly, from the docs:

In this example, the assignment expression helps avoid calling len() twice:

if (n := len(a)) > 10:     print(f"List is too long ({n} elements, expected <= 10)") 

b) Simplifying list comprehensions

for example:

stuff = [(lambda y: [y,x/y])(f(x)) for x in range(5)]

can become:

stuff = [[y := f(x), x/y] for x in range(5)]

Syntax and semantics

In any context where arbitrary Python expressions can be used, a named expression can appear. This is of the form name := expr where expr is any valid Python expression, and name is an identifier.

The value of such a named expression is the same as the incorporated expression, with the additional side-effect that the target is assigned that value

Differences from regular assignment statements

In addition to being an expression rather than statement, there are several differences mentioned in the PEP: expression assignments go right-to-left, have different priority around commas, and do not support:

  • Multiple targets
x = y = z = 0  # Equivalent: (z := (y := (x := 0))) 
  • Assignments not to a single name:
# No equivalent a[i] = x self.rest = [] 
  • Iterable packing/unpacking
# Equivalent needs extra parentheses  loc = x, y  # Use (loc := (x, y)) info = name, phone, *rest  # Use (info := (name, phone, *rest))  # No equivalent  px, py, pz = position name, phone, email, *other_info = contact 
  • Inline type annotations:
# Closest equivalent is "p: Optional[int]" as a separate declaration p: Optional[int] = None 
  • Augmented assignment is not supported:
total += tax  # Equivalent: (total := total + tax) 
like image 139
Chris_Rands Avatar answered Sep 29 '22 16:09

Chris_Rands


A couple of my favorite examples of where assignment expressions can make code more concise and easier to read:

if statement

Before:

match = pattern.match(line) if match:     return match.group(1) 

After:

if match := pattern.match(line):     return match.group(1) 

Infinite while statement

Before:

while True:     data = f.read(1024)     if not data:         break     use(data) 

After:

while data := f.read(1024):     use(data) 

There are other good examples in the PEP.

like image 30
Jonathon Reinhart Avatar answered Sep 29 '22 15:09

Jonathon Reinhart