Repository navigation
Expand file tree
/
Copy pathwalrus_operator.py
More file actions
121 lines (92 loc) 路 4.31 KB
/
Copy pathwalrus_operator.py
File metadata and controls
121 lines (92 loc) 路 4.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
"""
The walrus operator, also known as the assignment expression operator,
allows you to assign values to variables as part of an expression. This
feature was introduced in Python 3.8 through PEP 572.
The walrus operator uses the := syntax and is particularly useful in
reducing redundancy when you need to compute a value and then use it
in a condition or comprehension.
"""
class InputBuffer:
"""Simulate an interactive input buffer for while-loop demonstrations."""
def __init__(self, inputs: list[str]) -> None:
self._inputs = inputs
self._index = 0
def read_next(self) -> int:
"""Return next integer from inputs or 0 when exhausted."""
if self._index < len(self._inputs):
result = int(self._inputs[self._index])
self._index += 1
return result
return 0
def collect_until_zero(buffer: InputBuffer) -> list[int]:
"""Collect non-zero integers using walrus assignment in a while condition."""
numbers = []
while (num := buffer.read_next()) != 0:
numbers.append(num)
return numbers
def filter_by_length_range(words: list[str], min_len: int, max_len: int) -> list[str]:
"""Filter words with length strictly between min_len and max_len using walrus operator.
Assigning (word_len := len(word)) calculates length once and reuses it in
the second comparison, avoiding redundant len() calls per element.
"""
return [word for word in words if min_len < (word_len := len(word)) and word_len < max_len]
def filter_squares_below(numbers: list[int], limit: int) -> list[int]:
"""Filter squared numbers strictly below limit without redundant calculations.
Assigning (square := n * n) in the filter condition allows reusing the
result directly in the comprehension output expression.
"""
return [square for n in numbers if (square := n * n) < limit]
def map_long_word_lengths(words: list[str], min_len: int) -> dict[str, int]:
"""Build a mapping of words to lengths exceeding min_len using walrus.
Assigning (word_len := len(word)) in the filter allows using the calculated
length directly as the dictionary value.
"""
return {word: word_len for word in words if (word_len := len(word)) > min_len}
def main() -> None:
# 1. Condition expressions: traditional vs walrus operator
text = "Hello, Python!"
length = len(text)
if length > 5:
assert length == 14
# With the walrus operator, assign and check in one expression
text2 = "Ultimate"
if (length2 := len(text2)) > 5:
assert length2 == 8
# 2. While loop: traditional approach requires duplicating input reading logic
# Simulating a user providing 5 then 0
numbers_old = []
n = int("5")
while n != 0:
numbers_old.append(n)
n = int("0")
assert numbers_old == [5]
# With the walrus operator in while condition via InputBuffer
buffer = InputBuffer(["3", "7", "0"])
assert collect_until_zero(buffer) == [3, 7]
assert buffer.read_next() == 0
# 3. List comprehension: avoid computing len() twice per item
data = ["apple", "banana", "cherry", "date"]
long_words_old = [word for word in data if len(word) > 5 and len(word) < 7]
assert long_words_old == ["banana", "cherry"]
assert filter_by_length_range(data, 5, 7) == ["banana", "cherry"]
# Filtering and transforming simultaneously without recomputing squares
numbers = [3, 5, 7, 9, 11]
squares_old = [n * n for n in numbers if n * n < 50]
assert squares_old == [9, 25, 49]
assert filter_squares_below(numbers, 50) == [9, 25, 49]
# 4. Set comprehension with walrus operator
words = ["hi", "hello", "world", "python", "code"]
long_lengths = {word_len for word in words if (word_len := len(word)) > 4}
assert long_lengths == {5, 6}
# 5. Dictionary comprehension with walrus operator
assert map_long_word_lengths(words, 4) == {"hello": 5, "world": 5, "python": 6}
# 6. Enclosing scope: variables assigned with := in comprehensions leak to enclosing scope
[result for x in [1, 2, 3] if (result := x * 2) > 2]
assert result == 6
# 7. Nested walrus expressions
values = [1, 2, 3, 4, 5]
if (total := sum(doubled := [x * 2 for x in values])) > 15:
assert doubled == [2, 4, 6, 8, 10]
assert total == 30
if __name__ == "__main__":
main()