Unpacking and Destructuring¶
Python provides powerful syntax for extracting values from sequences and assigning them to multiple variables.
Basic Unpacking¶
Tuple Unpacking¶
point = (10, 20)
x, y = point
print(x, y) # 10 20
List Unpacking¶
data = [1, 2, 3]
a, b, c = data
print(a, b, c) # 1 2 3
String Unpacking¶
chars = "ABC"
a, b, c = chars
print(a, b, c) # A B C
Star Unpacking (Extended Unpacking)¶
Collect Remaining Elements¶
first, *rest = [1, 2, 3, 4, 5]
print(first) # 1
print(rest) # [2, 3, 4, 5]
First and Last¶
first, *middle, last = [1, 2, 3, 4, 5]
print(first) # 1
print(middle) # [2, 3, 4]
print(last) # 5
Ignore with Underscore¶
first, *_, last = range(10)
print(first, last) # 0 9
Head and Tail Pattern¶
head, *tail = [1, 2, 3, 4, 5]
# head = 1
# tail = [2, 3, 4, 5]
Nested Unpacking¶
Nested Tuples¶
data = [(1, 2), (3, 4)]
(a, b), (c, d) = data
print(a, b, c, d) # 1 2 3 4
Mixed Structures¶
data = (1, [2, 3], 4)
a, [b, c], d = data
print(a, b, c, d) # 1 2 3 4
Deep Nesting¶
data = [(1, 2), (3, 4), (5, 6)]
(a, b), (c, d), (e, f) = data
print(a, b, c, d, e, f) # 1 2 3 4 5 6
Destructuring Patterns¶
Function Return Values¶
def get_coords():
return 10, 20, 30
x, y, z = get_coords()
print(x, y, z) # 10 20 30
Ignore Unwanted Values¶
def stats():
return 100, 50, 75 # mean, min, max
mean, _, _ = stats() # Only want mean
print(mean) # 100
Dictionary Access¶
person = {'name': 'Alice', 'age': 30}
# Extract specific values
name, age = person['name'], person['age']
# Or use .values() if order is guaranteed (Python 3.7+)
name, age = person.values()
Loop Destructuring¶
points = [(1, 2), (3, 4), (5, 6)]
for x, y in points:
print(f"x={x}, y={y}")
Enumerate Destructuring¶
items = ['a', 'b', 'c']
for i, item in enumerate(items):
print(f"{i}: {item}")
Dictionary Items¶
person = {'name': 'Alice', 'age': 30}
for key, value in person.items():
print(f"{key}: {value}")
Dictionary Unpacking¶
Function Arguments¶
def func(a, b, c):
return a + b + c
data = {'a': 1, 'b': 2, 'c': 3}
result = func(**data) # Unpack dict as keyword args
print(result) # 6
Merging Dictionaries¶
dict1 = {'a': 1, 'b': 2}
dict2 = {'c': 3, 'd': 4}
merged = {**dict1, **dict2}
print(merged) # {'a': 1, 'b': 2, 'c': 3, 'd': 4}
Walrus Operator (:=)¶
The walrus operator (Python 3.8+) assigns a value and returns it in a single expression.
Basic Syntax¶
# := assigns AND returns value
if (n := len(data)) > 10:
print(f"Long list: {n} items")
Avoiding Repeated Computation¶
# Before (computes len twice)
data = input()
if len(data) > 5:
print(f"Long: {len(data)}")
# After (computes once)
if (n := len(data)) > 5:
print(f"Long: {n}")
While Loops¶
# Read until empty
while (line := input("Enter: ")) != "":
print(f"You entered: {line}")
List Comprehensions¶
# Reuse computed value
results = [y for x in data if (y := expensive(x)) > 0]
Pattern Matching¶
import re
if (match := re.search(r'\d+', text)):
print(f"Found number: {match.group()}")
If-Elif Chains¶
if (match := pattern1.search(text)):
handle_pattern1(match)
elif (match := pattern2.search(text)):
handle_pattern2(match)
else:
handle_no_match()
Summary¶
| Pattern | Syntax | Example |
|---|---|---|
| Basic unpacking | a, b = iterable |
x, y = (1, 2) |
| Star unpacking | first, *rest = iterable |
head, *tail = [1,2,3] |
| Nested | (a, b), (c, d) = nested |
(x, y), z = ((1,2), 3) |
| Ignore values | a, _, c = iterable |
first, *_, last = data |
| Dict unpacking | **dict |
func(**kwargs) |
| Walrus | (name := expr) |
if (n := len(x)) > 0: |
Key points:
- Use unpacking to extract values cleanly
- * collects remaining elements into a list
- _ is convention for ignored values
- Walrus operator combines assignment and expression
- Works in loops, comprehensions, and conditions