Hint: You can adjust the default video playback speed in your account settings.
Hint: You can set your subtitle preferences in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please refer to our video player troubleshooting guide for assistance.

Immutable Data Structures: Tuples

In the previous lesson, you stored your immutable data structures (namedtuple) in an mutable one (list). Now, you’ll see how you can replace that list with a tuple, which is like a list but immutable:

import collections

Scientist = collections.namedtuple('Scientist', [

scientists = (
    Scientist(name='Ada Lovelace', field='math', born=1815, nobel=False),
    Scientist(name='Emmy Noether', field='math', born=1882, nobel=False),
    Scientist(name='Marie Curie', field='math', born=1867, nobel=True),
    Scientist(name='Tu Youyou', field='physics', born=1930, nobel=True),
    Scientist(name='Ada Yonath', field='chemistry', born=1939, nobel=True),
    Scientist(name='Vera Rubin', field='chemistry', born=1928, nobel=False),
    Scientist(name='Sally Ride', field='physics', born=1951, nobel=False),

Now, you can access all of your data by index, but you’re no longer in danger of tampering with it. That’s exactly what you want to have when you’re taking a functional programming approach with a data set!

00:00 I think the best way to handle this is—instead of making a list,

00:08 we’re going to create a tuple, because a tuple is a immutable data structure in

00:14 Python. It’s basically like an immutable list, so you can’t add items to it or you can’t remove items from it. The way I would represent this data set is sort of like this.

00:28 So now, when you look at scientists here—let’s make it look kind of good, That’ll look pretty good if we pprint() it out—then it also formats really well.

00:40 What I have now is I have a tuple of Scientist objects. Previously, I had a list of dictionary objects. And so now, we’ve solved this immutability problem, I think, because now with this list of scientists I have now, I cannot go in there. I can’t delete anything.

01:00 I can’t modify this list, right? I can’t add new stuff to it.

01:05 I can’t do it, right? But I can still access everything by index here, and that’s pretty great. This would be an example of a immutable data structure, this whole thing here.

01:22 That would be an immutable array of these Scientist objects that are immutable, themselves, so the whole thing is immutable. In a perfect world, this is where you want to be if you’re doing any kind of functional programming in Python.

01:36 You want to start with a solid data structure that ideally is immutable. I mean, you know, you’re going to see in the examples that we’ll work through in the following videos, that you could totally do the same thing with dictionaries that are mutable or lists, but I think there’s a big benefit for thinking about how you can keep your data structures immutable if you’re trying to work with a functional programming style.

02:04 I hope you can start to see why this is useful. It’s going to become more obvious as we work through the other examples, but this is kind of the lead in to the other things that we’re going to cover next. So, what we’re going to look at next is a couple of functional programming primitives like the filter() function, the map() function, and the reduce() function and how those correspond to some other things that are actually built into Python, like list comprehensions.

02:33 This won’t be like a full-on, “Oh, this is how you should do all of your programs from now on in Python,” but it’ll more be like a fun dive into functional programming, so you can get some inspiration to maybe see how you can apply that style in your own programs. All right, I’ll see you there. Happy Pythoning!

Xavier on Nov. 12, 2019

Some mistakes in the field values which will result in different answers in Section 2 on the filter function. They should be:

scientists = (
    Scientist(name='Ada Lovelace', field='math', born=1815, nobel=False),
    Scientist(name='Emmy Noether', field='math', born=1882, nobel=False),
    Scientist(name='Marie Curie', field='physics', born=1867, nobel=True),
    Scientist(name='Tu Youyou', field='chemistry', born=1930, nobel=True),
    Scientist(name='Ada Yonath', field='chemistry', born=1939, nobel=True),
    Scientist(name='Vera Rubin', field='astronomy', born=1928, nobel=False),
    Scientist(name='Sally Ride', field='physics', born=1951, nobel=False),

victorariasvanegas on March 26, 2020

Really, really good explained concept.

abrophy89 on April 8, 2020

How do you get your editor to default to showing you the help information within the square as shown in your video when you are in interactive prompt?

Varun Vaddiparty on May 10, 2020

@abrophy89 he is using an alternate REPL called bpython. Check it out.

M Schulze on May 24, 2020

I wonder about the naming convention with Scientist in upper case, is this based on Type Variables Names?


Dan Bader RP Team on May 24, 2020

I’m following the naming convention for classes in PEP8, more here: realpython.com/lessons/python-naming-conventions/

adamgranthendry on April 21, 2021

@DanBader How do you use numpy in a functional fashion? Functional programming is great, but if I cannot use it for data science, I won’t have a realworld application for it.

Bartosz Zaczyński RP Team on April 22, 2021

@adamgranthendry That’s an interesting question. The two are somewhat orthogonal. NumPy provides a set of fairly low-level functions and data structures built for a specific purpose, while functional programming style is an abstract way of decomposing your problem into smaller pieces. It boils down to using pure functions, immutable data structures, and avoiding state mutation. Regardless of the underlying libraries in use, it’s up to you whether to follow those principles or not.

To give you an example, here’s the same function that relies on NumPy, written in a more and less functional style:

def curve(grades, curve_center, max_grade):
    return np.clip(grades + curve_center - grades.mean(), grades, max_grade)

The result of this function is always identical for the same set of input arguments since it doesn’t depend on some external state. There’s no intermediate state stored in variables, too, nor does the function mutate any value.


def curve(grades):
    average = grades.mean()
    change = CURVE_CENTER - average
    new_grades = grades + change
    return np.clip(new_grades, grades, 100)

Knowing where to draw the line between a functional and non-functional style is subjective. However, this one is arguably less functional, mainly due to an impure function. In other words, its result depends not only on the input arguments but also on a global variable.

Become a Member to join the conversation.