Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

This lesson is for members only. Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Hint: You can adjust the default video playback speed in your account settings.
Hint: You can set the default subtitles language 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 see our video player troubleshooting guide to resolve the issue.


Give Feedback

In this lesson, you’ll explore how lists can be nested. You’ve seen that an element in a list can be any sort of object. That includes another list. A list can contain sublists, which in turn can contain sublists themselves, and so on to arbitrary depth:

>>> x = ['a', ['bb', ['ccc', 'ddd'], 'ee', 'ff'], 'g', ['hh', 'ii'], 'j']
>>> x
['a', ['bb', ['ccc', 'ddd'], 'ee', 'ff'], 'g', ['hh', 'ii'], 'j']
>>> x[0]
>>> print(x[0], x[2], x[4])
a g j
>>> x[1]
['bb', ['ccc', 'ddd'], 'ee', 'ff']
>>> x[1][0]
>>> x[1][1]
['ccc', 'ddd']
>>> x[1][2]
>>> x[1][1][1]
>>> x[3][0]
>>> x[-2][-1]
>>> x[-4][-3][-2]

>>> x
['a', ['bb', ['ccc', 'ddd'], 'ee', 'ff'], 'g', ['hh', 'ii'], 'j']
>>> len(x)
>>> 'ddd' in x
>>> 'ddd' in x[1]
>>> 'ddd' in x[1][1]

00:00 This video is about nesting within lists. So, you’ve already seen that an element in a list can be any sort of object. That means that a list could be one of those objects.

00:10 You can have a list within a list, and that list can also have a list within it—and so on, and so on, like in this example.

00:19 For the object x, there’s three layers going on here. In index 0, 2, and 4, there’s a simple first layer, but then in index 1, there’s a second layer with its own indexes. And then in index 1 of that, x[1][1], there’s a third layer.

00:37 These sublists within the lists can be created pretty easily with additional square brackets.

00:45 Let me take you through this example. For this example, I’m going to have you recreate that list shown in the slides. At index 0 you start with the object 'a', and within that at index 1, you start with a sublist with 'bb' and then an additional sublist at its index 1, closing that sublist after two items.

01:07 Then close the other sublist after four items. So now you’re back down to the first level.

01:22 Type in x, you can see that it’s a complete list. So, can you index it? Sure! That first index would be 'a'. In fact, I’ll show you all three together.

01:32 Here’s index 0, index 2, and index 4.

01:37 So a, g, and j. Now, index 1 is a sublist, and inside of it, it has another sublist. If you wanted to access that sublist, it’s done by adding another index set with another pair of square brackets.

01:53 So if you want to access 'ccc', that would be index x[1]—well, here 0 is going to be 'bb'. If you want to get to the second value here, that would be here. This is going to return both of these items. Okay, in fact, well, let’s go a little further. x[1][2] is going to be 'ee', okay. But what if you wanted to just get to 'ddd' here?

02:17 That’d be x[1][1][1]. That’s taking the second index—again, everything’s zero-based, right? So here, grabbing this. Then by doing x[1][1], we got this. Now, if we want to get this guy, that’s one more index.

02:34 That’s going to get you 'ddd'. Similarly, if you wanted to grab items in this sublist. Well, that’s way down here, so index 0, 1, 2, 3x[3]. And if you wanted to grab the first element, that would be [0]. And negative indexing works here too.

02:53 So if you were to say x[-2], which would grab this guy here, and [-1]—that should give me 'ii'. Right. Versus x[-4] and then [-3]. And let’s say we want 'cc'.

03:12 That would be [-2].

03:17 So again, here’s x. What is the length of x? How many objects does it have? It only has five objects: one, two, three, four, five.

03:27 So, this is a sublist, and this is a sublist, those are objects within it, and then this list even has another sublist within it also. But as far as objects go, there’s only five total in the main list of x.

03:40 So if we’re practicing with the operators again, what if you were to say is the string 'ddd' in x? Well, it says that’s False, because this is only searching the first level.

03:52 Even if you were to say, “Okay, well, I know that it’s in x[1]. It’s part of that. It’s a sublist of that.” Nope! It will not search inside of a sublist automatically.

04:03 You’d have to specify all the way inside here, so you’ve got to go inside of not only index 1 of this whole list—getting this object—but then inside this object here, which is, again, the second index. That would return True because it’s a member of this list here. An individual element in a sublist doesn’t count as an element of the parent list.

04:26 It only counts as an element of its own list.

04:30 Next up, you’ll learn about how lists are mutable and dynamic.

Hello Sir, what are some good use cases of NESTED LISTS?

Chris Bailey RP Team on Dec. 31, 2019

Hi km! The best case I can think of is a Matrix, or an array, sort of like a spreadsheet. Where you have could have columns and rows of data. It could look like my_matrix = [['Houston', 'Honolulu', 'Denver', 'Los Angeles'],[95.6, 81.1, 65.2, 73.4], [92.9, 80.4, 67.0, 70.1], [100.6, 79.9, 80.2, 72.8]] where the first row are the city names, followed by temperature data for those cities across 3 more rows. There are few Python packages that specialize in working with this type of data, Numpy and Pandas which uses Numpy.

km on Jan. 2, 2020

Thanks a lot Chris, let me try them out

koellingh on March 27, 2020

I was curious if the min() and max() functions would support both ints and floats in the same list. my initial impulse was that it would not, but it worked. Do floats have ascii values? are ints and floats not compared using ascii values?

Chris Bailey RP Team on March 27, 2020

Hi @koellingh, I think this question is somewhat based on the previous lesson, with min() and max(). Floats and integers can be compared using min and max, because of how Python handles numbers. “Python fully supports mixed arithmetic: when a binary arithmetic operator has operands of different numeric types, the operand with the “narrower” type is widened to that of the other, where integer is narrower than floating point, which is narrower than complex. A comparison between numbers of different types behaves as though the exact values of those numbers were being compared.” From the python docs about numeric types.

In the case of comparing individual ASCII characters using max() and min(), those functions are using the ordinal/ASCII value.

If you try to compare a mix of characters or strings with numbers using those functions you will get an Error: `TypeError: ‘>’ not supported between instances of ‘int’ and ‘str’.

koellingh on March 27, 2020

Ah, that is very helpful. I understand this now. If ints were treated as ascii values, then there wouldn’t be an error when the min() or max() functions run on a list with both ints and strings. The error is because it is treating ints as ordinals and strings as ascii values, and ordinals and strings cannot be compared together. And ints and floats are both ordinals.

DoubleA on Jan. 30, 2021

Hi Chris! Thanks for such a clear tutorial! I am learning a lot from you guys. Playing with list I have now something to add which is perhaps worth mentioning here. Here’s my code snippet:

import copy
my_list = ['a', ['b', 'c', ['d', 'e', 'f'], 'g', 'h'], 'j', 'i', ['m', ['k', 'l'], 'n']]
deep_copy = copy.deepcopy(my_list)
shallow_copy = my_list.copy()
my_list[1][2][0] = '_d_'  # I assign a different value to the chosen element of my_list
print(shallow_copy)       # the element [1][2][0] of the shallow_copy list has also been affected! 
print(deep_copy)          # the element [1][2][0] of the deep_copy list has not been affected! 

# Copying my_list using the list() function and the slice [:] operator crates also a shallow copy of my_list

my_second_list = list(my_list)
my_third_list = my_list[:]
my_list[1][2][1] = '_e_'
print(my_second_list)  # the element of my_second_list[1][2][1] has also been affected
print(my_third_list)   # the element of my_third_list[1][2][1] has also been affected

One can conclude that it should be borne in mind that simple “copying” of a nested list does not propagate to the nested elements of the copy. I think, there’s a parallel with the “in” operator which, as was demonstrated, did not “see” the nested elements and treated them as standalone or separate lists. Copying nested list using tools other than the .deepcopy() method creates shallow copies of the original list and every change to the “parent” list will also be reflected in the subsequent copies.

Become a Member to join the conversation.