Tuples: Immutable, not Inflexible

Tuples: Immutable, not Inflexible

There seems to be a trouble with tuples: some Python developers don’t fully understand how they’re different from lists don’t know what they’re supposed to do with them. In this article, we’ll clear up the differences between tuples and lists as well as show how useful they can be in real code.

Tuples vs. Lists
Lists (which we’ve discussed before) and tuples are both sequence data types which contain comma-separated items, and thus both support a lot of the same operations, like item access by both index and slice.

Lists are mutable sequences which can contain mutable items (like other lists) and immutable items (like tuples, strings or numbers), and are analogous to arrays in C. Tuples, however are immutable, but can contain mutable objects like lists or immutable items (including other tuples). This means that you can change the members of a list after you’ve created it, but you can’t do the same with tuples. Because tuples are immutable, they can be a good choice for containing data that you don’t want inadvertently changed as it’s used (e.g. by a method which modifies the original instead of returning a copy).

In practice, however the immutability of tuples commonly feels more like a restriction than an advantage over lists, so Python devs can be tempted to always use lists whenever they need a compartmentalized bucket to hold their data. As a result, the tuple becomes the list’s eccentric aunt.

Instead, tuples should be thought of as similar to C structs instead of immutable lists. This is because tuples are often used to store a collection of different data types whereas members in list are usually the same data type.

What Can You Do with Tuples?
Python’s official documentation says that tuples are generally used for some purposes and lists for different ones, but doesn’t mention any tasks which explicitly require tuples, like how lists are perfect for implementing a stack (LIFO queue), or how dictionaries are great for lookup tables (LUTs).

One of the most important uses for tuples is within Python itself: function argument lists are tuples.

But what can tuples do that lists can’t?

Packing and unpacking, for starters. This is much easier than iterating over a list and it’s a really a handy way to distribute and condense data in your program:

>>>letters = "a", "b", "c"
>>>letters
('a', 'b', 'c')
>>> first, second, third = letters
>>>first
'a'
>>>second
‘b’
>>>third
‘c’

and it’s also what makes multiple assignment possible:

>>>a,b = first, second
>>>a
‘a’
>>>b
‘b’

Another thing you can do with with tuples: use them as a key for a dict if no mutable object is contained in the tuple directly or indirectly. The whole tuple is used as the key, not any one of the individual members:

>>>t = "one", "two"
>>t2 = "three", "four"
>>>d = {t: "first", t2: "second"}
>>>d[t] ‘first’

Which is something you can’t do with a list:

lst = ["one", "two"]
lst2 = ["three", "four"]
d_lst = {lst: "first", lst2: "second"}

Traceback (most recent call last):
  File "<pyshell#10>", line 1, in <module>
    d_lst = {lst: "first", lst2: "second"}
TypeError: unhashable type: 'list'

This can be very useful for implementing logic tables or multivariable LUTs. The latter can speed up code which often uses the same multiple inputs for a computationally expensive function:

inputs = 1, 2, 3

lut = {(1,2,3): 14, (4,5,6): 59083}

if inputs in lut:
     return(lut[inputs])
else:
     var1, var2, var3 = inputs
     return(some_really_expensive_computation(var1, var2, var3))

Tuples’ immutability, coupled with their ability to be easily packed and unpacked, can be very useful in Python programs. They provide your data a secure vault and make multiple assignment possible. There’s no trouble with tuples, once you get to know them.

Copyright © Python People