Skip to content

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