* much of this material is based on Brett Slatkin's Effective Python 2nd ed., which I highly recommend.
Unpacking Assignments in Python involves assigning multiple values with one statement.
three_nice_numbers = [23, 19, 51] # unpacking first, second, third = three_nice_numbers print(first, second, 'and', third) # 23 19 and 51
This can be applied to any iterable-- any object that can return its members one at a time. For instance, it can be used to assign the values of a tuple to multiple varies in one line.
nice_number_tuple = (23, 19, 51) # unpacking first, second, third = nice_number_tuple print(first, second, 'and', third) # 23 19 and 51
This is easier to read and less error-prone as compared to accessing the iterable members via indexing and then assigning them separately.
nice_number_tuple = (23, 19, 51) # access via index and assign first = nice_number_tuple second = nice_number_tuple third = nice_number_tuple
Catch-All Unpacking | Starred Expressions
A drawback of assignment unpacking is that you must know the length of the iterable in advance. If you provide the incorrect number of variable names in the statement, you'll get an error:
nice_numbers = [23, 19, 51, 62, 54] # unpacking first, second, third = nice_numbers # ValueError: too many values to unpack (expected 3)
A neat way around this is to use starred expressions.
nice_numbers = [23, 19, 51, 62, 54] # unpacking first, second, *the_rest = nice_numbers # 23, 19, [51, 62, 54]
Starred expressions always become
list instances. You can place them anywhere in the assignment statement:
nice_numbers = [23, 19, 51, 62, 54] # unpacking first, *middle, last = nice_numbers # 23, [19, 51, 62], 54
If there aren't any leftover items to unpack, the starred expression becomes an empty list.
nice_numbers = [23, 54] # unpacking first, *middle, last = nice_numbers # 23, , 54
Watch out for memory exhaustion when using starred expressions
- Because the starred expression always becomes a list, in some cases you run the risk of exhausting your computer's memory and causing program termination. So, it is best to use this only if you are sure the resulting data will fit into memory.
Don't use more than three variables in unpacking statements
- It's best to avoid cases where you'll need more than three variables to unpack an iterable or data returned from some function. Having four or more is both error-prone and hurts readability.
# don't do this def get_stats(): ... return minimum, maximum, median, average, count # Unpacking Correctly minimum, maximum, median, average, count = get_stats() # Wrong Order, but hard to tell minimum, maximum, average, median, count = get_stats()
Moreover, if the
get_stats function took arguments, the last line of code would likely become very long and require wrapping, making the code less readable.
If more than three values needs to be returned and distinctly gotten from a function/iterable, consider using a
namedtuple from Python's
from collections import namedtuple # define the namedtuple and instantiate it with the return values in the function def get_stats(): ... Stats = namedtuple('Stats', 'min max median average') stats = AggregateStats(minimum, maximum, median, average) return stats aggregate_stats = get_stats() print('The median is', aggregate_stats.median)