Lessons From Advent of Code: Tuple Unpacking
Tags: python, adventofcode, beginners
Published: 2019-12-25 21:30:41

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](https://adventofcode.com/2019/day/2). I actually solved this one myself, so I'll be comparing aspects of [my solution](https://github.com/erik-kristofer-anderson/advent-of-code/tree/master/day02) with that by [Joel Grus](https://github.com/joelgrus/advent2019/blob/master/day02/day02.py).

One quickly apparent difference is that he used tuple unpacking to simplify a portion of the code.  
Tuple unnpacking works like this:
```python
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:
```python
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!
```python
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:
```python
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.

``` python
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!