Tuple Unpacking

Tuple Unpacking

Python has a very neat tuple-related feature, called “tuple unpacking”

Tuple unpacking (a.k.a. multiple assignment) can be used to “unpack” an iterable (list, tuple, etc.) into multiple variables at once:

>>> x, y = 4, 5
>>> x
4
>>> y
5
>>> x, y
(4, 5)

This is called “tuple unpacking” because it looks like we have a tuple on the left-hand side of that equals sign. We can unpack any iterable.

Parenthesis are optional so all of these work also:

>>> (x, y) = 4, 5
>>> x, y = (4, 5)
>>> (x, y) = (4, 5)

The left side of the assignment must have the same number of variables as the number of elements of the tuple on the right. If they don’t match, an exception will be raised:

>>> coordinates = 3, 4, 5
>>> x, y = coordinates
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: too many values to unpack (expected 2)

As we discussed earlier, tuples are also used for returning multiple values from a function.

>>> def split_name(name):
...     first, last = name.rsplit(" ", 1)
...     return first, last
...
>>> first_name, last_name = split_name("Trey Hunner")
>>> first_name
'Trey'
>>> last_name
'Hunner'
>>> split_name("Trey Hunner")
('Trey', 'Hunner')

It’s important to understand how tuple unpacking works because it is a very common construct in Python, so you will see tuple unpacking a lot. We’ll use it quite a bit later when we learn about looping.

Tuple Exercises

Hint

If you get stuck for a minute or more, try searching Google or using help.

If you’re stuck for more than a few minutes, some of these links might be helpful for some of the exercises below:

Hot Dog Packs

File: Edit the hotdog_counts function in the tuples.py file that is in the exercises directory.

Test: Run python test.py hotdog_counts in your exercises directory.

Exercise: We’re hosting a party and we need to know how many hot dog buns and hot dogs we need.

Buns and dogs are sold in packs of different sizes:

  • 8 buns are in 1 pack of buns

  • 10 hot dogs are in 1 pack of dogs

Create a function hotdog_counts which accepts the number of guests and returns a two-item tuple containing the number of bun packs and the number of dog packs we need (bun packs first, dog packs second).

>>> from tuples import hotdog_counts
>>> hotdog_counts(7)
(1, 1)
>>> hotdog_counts(10)
(2, 1)
>>> hotdog_counts(14)
(2, 2)
>>> hotdog_counts(20)
(3, 2)
>>> hotdog_counts(21)
(3, 3)

Hint

You’ll need to calculate how many packs are needed by dividing and rounding up. Use math.ceil() to round upward, or use integer division with a trick.

Parse Time

File: Edit the parse_time function in the file functions.py that is in the exercises directory.

Test: Run python test.py parse_time in your exercises directory.

Exercise: Edit the function parse_time so that it takes an input time string in the format of “minutes:seconds”, uses tuple unpacking to extract the minutes and seconds, calculates and returns the total number of seconds. You can assume the string will contain at least one digit each for minutes and seconds.

>>> from functions import parse_time
>>> parse_time("4:03")
243
>>> parse_time("0:12")
12
>>> parse_time("1:10")
70

Format Time

File: Edit the format_time function in the file functions.py that is in the exercises directory.

Test: Run python test.py format_time in your exercises directory.

Exercise: Edit the function format_time so that it takes an integer value of seconds and calculates minutes and seconds, then returns a string of “minutes:seconds”. If the value of seconds is less than 10, a zero should be prefixed so the seconds are always 2 digits.

>>> from functions import format_time
>>> format_time(90061)
'1501:01'
>>> format_time(0)
'0:00'
>>> format_time(3600)
'60:00'
>>> format_time(301)
'5:01'
>>> format_time(3715)
'61:55'
>>> format_time(61)
'1:01'
>>> format_time(119)
'1:59'
>>> format_time(333)
'5:33'

Swap Ends

File: Edit the swap_ends function in the tuples.py file that is in the exercises directory.

Test: Run python test.py swap_ends in your exercises directory.

Exercise: Edit the function swap_ends so that it swaps the first and last items in a given list, in-place.

>>> from tuples import swap_ends
>>> numbers = [1, 2, 3, 4, 5]
>>> swap_ends(numbers)
>>> numbers
[5, 2, 3, 4, 1]

Earliest

File: Edit the get_earliest function in the tuples.py file that is in the exercises directory.

Test: Run python test.py get_earliest in your exercises directory.

Exercise: Make function get_earliest that accepts two dates in MM/DD/YYYY format and returns the date that is earliest.

>>> from tuples import get_earliest
>>> get_earliest("01/27/1832", "01/27/1756")
'01/27/1756'
>>> get_earliest("02/29/1972", "12/21/1946")
'12/21/1946'
>>> get_earliest("03/21/1946", "02/24/1946")
'02/24/1946'
>>> get_earliest("06/24/1958", "06/21/1958")
'06/21/1958'

Note

Want to test this out manually (instead of using python test.py)?

You could could create a file called get_earliest_test.py with your own test code:

from tuples import get_earliest

print('Calling get_earliest("01/27/1832", "01/27/1756")')
print("Expected: 01/27/1756")
print("  Actual:", get_earliest("01/27/1832", "01/27/1756"))

print()

print('Calling get_earliest("02/29/1972", "12/21/1946")')
print("Expected: 12/21/1946")
print("  Actual:", get_earliest("02/29/1972", "12/21/1946"))

print()

print('Calling get_earliest("03/21/1946", "02/24/1946")')
print("Expected: 02/24/1946")
print("  Actual:", get_earliest("03/21/1946", "02/24/1946"))

print()

print('Calling get_earliest("06/24/1958", "06/21/1958")')
print("Expected: 06/21/1958")
print("  Actual:", get_earliest("06/24/1958", "06/21/1958"))

Then you can run that file to test your code:

$ python get_earliest_test.py

Name Key

File: Edit the name_key function in the tuples.py file that is in the exercises directory.

Test: Run python test.py name_key in your exercises directory.

Exercise: Write a function name_key that accepts a full name string and returns a last-first name tuple:

To test locally:

>>> from tuples import name_key
>>> suzanne = "Suzanne Smith"
>>> michael = "Michael Gambino"
>>> name_key(michael)
('Gambino', 'Michael')
>>> name_key(suzanne)
('Smith', 'Suzanne')

Sort Names

File: Edit the sort_names function in the tuples.py file that is in the exercises directory.

Test: Run python test.py sort_names in your exercises directory.

Exercise: Write a function sort_names that accepts a list of full name strings and returns a sorted list (using sorted with key).

The built-in sorted function accepts a key argument that determines how values should be sorted in a given iterable. You can use the name_key function you created above as the key argument.

Let’s use this function to sort a list of names. Names should be sorted by last name followed by first name (when the last names are equal).

>>> from tuples import sort_names
>>> names = ["Jill Moore", "Ben Speigel", "Tanya Jackson", "Evelyn Moore"]
>>> sort_names(names)
['Tanya Jackson', 'Evelyn Moore', 'Jill Moore', 'Ben Speigel']