Lessons From Advent of Code: Tuple Unpacking
Erik Anderson
Posted on December 25, 2019
About 15 days ago, I gave up on Advent of Code for this year. Partly because I wanted to focus on finishing a comp sci certificate and prepare for a data science bootcamp. But also because they were getting hard. Now that it's Christmas, I'm letting myself look at solutions.
SPOILER ALERT: This post includes solutions to Advent of Code 2019 Day 02.
To add some learning value to this, I'll be writing some blog posts on lessons I learn from those solutions. I'll start with Day 02. I actually solved this one myself, so I'll be comparing aspects of my solution with that by Joel Grus.
One quickly apparent difference is that he used tuple unpacking to simplify a portion of the code.
Tuple unnpacking works like this:
In [1]: a, b, c = 3, 4, 5
In [2]: a
Out[2]: 3
In [3]: b
Out[3]: 4
In [4]: c
Out[4]: 5
As you can see, the code in line In [1]:
assigns 3
to a
, 4
to b
, and 5
to c
. But why did that work?
Let's back up. A tuple is a fundamental data structure in python. The syntax to create a tuple is like this:
In [7]: my_tuple = 3, 4, 5, 'foo', 'bar'
In [8]: my_tuple
Out[8]: (3, 4, 5, 'foo', 'bar')
Note also that you will some times see things like my_tuple = (3, 4, 5, 'foo', 'bar')
, but these parentheses are not strictly required.
Tuples in python are like lists, except that they are immutable; once created they cannot be changed.
Like lists, tuples can contain different data types; in this case we saw int
and str
.
On the line a, b, c = 3, 4, 5
, a few steps happen in the background. (3, 4, 5)
gets packaged as a tuple. Then python attempts to store this tuple to the variable on the left side of the equation. Finding not one variable, but the tuple of variables (a, b, c)
, it unpacks both (3, 4, 5)
and (a, b, c)
, matching up the numberes and variables in order.
Note that this process is also called multiple assignment because, well, it assigns multiple variables in one line.
What is this useful for? Here's one use case from Joel's solution.
But first I'll show a (out of context) portion of my (rather ugly) solution. Don't worry too much about what is happening, just note the convoluted syntax. That's a lot of info packed onto one line!
elif tape[current_index] == 1:
tape[tape[current_index + 3]] = tape[tape[current_index + 1]] + tape[tape[current_index + 2]]
That's a long, intricate line. It would be nice if we could shorten it.
Joel does this by specifying opcode = program[pos]
, loc1 = program[pos + 1]
, loc2 = program[pos + 2]
, loc3 = program[pos + 3]
, leading to code that looks like this:
if opcode == 1:
program[loc3] = program[loc1] + program[loc2]
The code to assing opcode
, loc1
, loc2
and loc31
could go on four separate lines, but here's where tuple unpacking becomes relevant. Joel does all of those assignments in one line.
opcode, loc1, loc2, loc3 = program[pos], program[pos + 1], program[pos + 2], program[pos + 3]
That code (on the second line of this sample) creates a tuple of integers on the right ride and passes it to the left side, where it gets unpacked into opcode
, loc1
, loc2
, and loc3
.
What's the advantage? It saves 3 lines of code. Maybe that's a small gain for a whole blog post, but tuple unpacking gets used in a wide variety of situations in Python.
And there's tuple unpacking applied to assignment, all wrapped up for Christmas!
Posted on December 25, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.