Skip to content

Commit 6d6fc78

Browse files
committed
[Walrus Operator] Add concept
1 parent 7e5a83d commit 6d6fc78

3 files changed

Lines changed: 110 additions & 11 deletions

File tree

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"blurb": "TODO: add blurb for this concept",
3-
"authors": ["bethanyg", "cmccandless"],
2+
"blurb": "Properly called assignment expressions, the walrus operator assigns values to variables as part of a larger expression.",
3+
"authors": ["BethanyG", "colinleach"],
44
"contributors": []
55
}

‎concepts/walrus-operator/about.md‎

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,101 @@
1-
#TODO: Add about for this concept.
1+
# About
22

3+
Added in Python 3.8, assignment expressions use the `:=` operator, popularly called the ["walrus operator"][whats-new].
4+
5+
The central idea is that a variable can be assigned within the context of another statement.
6+
A simple example is when something tested in a condition is needed again within the body of an `if` statement:
7+
8+
```python
9+
# without walrus operator
10+
a = 'short'
11+
if len(a) < 10:
12+
print(f"{len(a)} characters is too short")
13+
14+
# => "5 characters is too short"
15+
16+
# with walrus operator
17+
# Note the parentheses around the assignment (necessary)
18+
if (n := len(a)) < 10:
19+
print(f"{n} characters is too short")
20+
21+
# => "5 characters is too short"
22+
```
23+
24+
Thus, setting the `n` variable saves calculating `len(a)` twice.
25+
The saving is fairly trivial in this case, but becomes significant for a more expensive operation such as file I/O:
26+
27+
```python
28+
# Loop over fixed length blocks
29+
while (block := f.read(256)) != '':
30+
process(block)
31+
```
32+
33+
## Use cases
34+
35+
The walrus operator was [controversial][controversy] in the Python community when [first introduced][pep-572] in 2018.
36+
It is now an established part of the core language, simplifying code in some particular situations, but should not be over-used.
37+
As so often in programming, we should consider if use of a feature increases or decreases the readability of the code.
38+
39+
Some applications of the walrus operator are listed below.
40+
41+
### Comprehensions
42+
43+
List comprehensions, dictionary comprehensions, generator expressions, _etc_, all allow Python to do a lot in a terse piece of code.
44+
45+
Including a walrus operator can _sometimes_ make such code shorter and clearer, especially if a value calculated in the `if` clause is also needed in other parts of the comprehension.
46+
47+
```python
48+
[clean_name.title() for name in names
49+
if (clean_name := name.strip().lower()) in allowed_names]
50+
```
51+
52+
Note that the calculated value `clean_name` is only in scope within the comprehension.
53+
It cannot be used in other parts of the program.
54+
55+
### RegEx matching
56+
57+
Use of the walrus operator can simplify nested `if...else` statements.
58+
Handling regular expression matches is [an example][walrus-blog] of this:
59+
60+
```python
61+
import re
62+
63+
test = "Something we want to search"
64+
pattern1 = r"^.*(thing).*"
65+
pattern2 = r"^.*(missing).*"
66+
67+
# without walrus
68+
m = re.match(pattern1, test)
69+
if m:
70+
print(f"Matched the 1st pattern: {m.group(1)}")
71+
else:
72+
m = re.match(pattern2, test)
73+
if m:
74+
print(f"Matched the 2nd pattern: {m.group(1)}")
75+
# => "Matched 1st pattern: 'thing'"
76+
77+
# Cleaner with walrus
78+
if m := (re.match(pattern1, test)):
79+
print(f"Matched 1st pattern: '{m.group(1)}'")
80+
elif m := (re.match(pattern2, test)):
81+
print(f"Matched 2nd pattern: '{m.group(1)}'")
82+
# => "Matched 1st pattern: 'thing'"
83+
```
84+
85+
### Inside f-strings
86+
87+
This is not a particularly common use of walrus operators, but it can sometimes simplify code.
88+
As usual, the assignment must be within parentheses.
89+
90+
```python
91+
from datetime import datetime
92+
93+
print(f"Today is: {(today:=datetime.today()):%Y-%m-%d}, which is {today:%A}")
94+
95+
# => "Today is: 2024-01-06, which is Saturday"
96+
```
97+
98+
[whats-new]: https://docs.python.org/3/whatsnew/3.8.html#assignment-expressions
99+
[walrus-blog]: https://martinheinz.dev/blog/79
100+
[pep-572]: https://peps.python.org/pep-0572/
101+
[controversy]: https://dev.to/renegadecoder94/the-controversy-behind-the-walrus-operator-in-python-4k4e
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
[
22
{
3-
"url": "http://example.com/",
4-
"description": "TODO: add new link (above) and write a short description here of the resource."
3+
"url": "https://docs.python.org/3/whatsnew/3.8.html#assignment-expressions/",
4+
"description": "A What's New description for Python 3.8."
55
},
66
{
7-
"url": "http://example.com/",
8-
"description": "TODO: add new link (above) and write a short description here of the resource."
7+
"url": "https://peps.python.org/pep-0572/",
8+
"description": "PEP 572 describes the walrus operator and its rationale."
99
},
1010
{
11-
"url": "http://example.com/",
12-
"description": "TODO: add new link (above) and write a short description here of the resource."
11+
"url": "https://martinheinz.dev/blog/79/",
12+
"description": "A thoughtful blog article from Martin Heinz."
1313
},
1414
{
15-
"url": "http://example.com/",
16-
"description": "TODO: add new link (above) and write a short description here of the resource."
15+
"url": "https://dev.to/renegadecoder94/the-controversy-behind-the-walrus-operator-in-python-4k4e/",
16+
"description": "A discussion of the controversy surrounding the walrus operator when it was introduced."
1717
}
1818
]

0 commit comments

Comments
 (0)