7.2. Tuple Unpacking#
import sys
from pathlib import Path
# Find project root by looking for _config.yml
current = Path.cwd()
for parent in [current, *current.parents]:
if (parent / '_config.yml').exists():
project_root = parent
break
else:
project_root = Path.cwd().parent.parent
# Add project root to path
sys.path.insert(0, str(project_root))
# Import shared teaching helpers and cell magics
from shared import thinkpython, diagram, jupyturtle, structshape
from shared.download import download
7.2.1. Basic Unpacking#
You can assign multiple variables from a tuple or any sequence.
a, b = 1, 2
Values are assigned left to right. In this example, a gets 1 and b gets 2.
We can display the results like this:
a, b
(1, 2)
More generally, if the left side is a tuple of variables, the right side can be any sequence - a string, list, or tuple. For example, to split an email address into a user name and domain:
email = 'monty@python.org'
username, domain = email.split('@')
split returns a list with two elements; the first goes to username, the second to domain.
username, domain
('monty', 'python.org')
The number of variables on the left and values on the right must match; otherwise you get a ValueError.
%%expect ValueError
a, b = 1, 2, 3
ValueError: too many values to unpack (expected 2)
Tuple assignment is a clean way to swap two variables. With conventional assignments, you need a temporary variable:
temp = a
a = b
b = temp
That works, but tuple assignment does the same swap without a temporary variable.
a, b = b, a
### Exercise: Tuple Assignment
# 1. Unpack the tuple (10, 20, 30) into three variables x, y, z and print them.
# 2. Split the email address 'ada@lovelace.org' into username and domain using
# split('@') and tuple assignment, then print both.
# 3. Swap the values of two variables a=5, b=99 using tuple assignment.
### Your code starts here.
### Your code ends here.
10 20 30
ada lovelace.org
99 5
7.2.2. Starred Unpacking#
Use a starred name to capture “the rest” of a sequence during assignment.
first, *middle, last = range(6)
first, middle, last
(0, [1, 2, 3, 4], 5)
This works because all expressions on the right side are evaluated before any assignments.
Tuple assignment is also handy in for loops.
For example, to loop through the items in a dictionary, use the items method.
d = {'one': 1, 'two': 2}
print(type(d.items()))
for item in d.items(): # items() returns a dict_items view of key-value pairs
key, value = item
print(key, '->', value)
<class 'dict_items'>
one -> 1
two -> 2
Each time through the loop, item is a tuple with a key and its value.
We can unpack it directly:
for key, value in d.items():
print(key, '->', value)
one -> 1
two -> 2
### Exercise: Starred Unpacking
# Given data = (1, 2, 3, 4, 5, 6)
# 1. Unpack the first element into `head`, the last into `tail`,
# and everything in between into `body` using starred unpacking.
# 2. Print all three.
# 3. Loop over {'x': 10, 'y': 20, 'z': 30}.items() and unpack
# each key-value pair directly in the for statement, printing each pair.
### Your code starts here.
data = (1, 2, 3, 4, 5, 6)
### Your code ends here.
1 [2, 3, 4, 5] 6
x -> 10
y -> 20
z -> 30
Now key and value are assigned on each iteration.