The Python list is one of the most used Python data structures, together with dictionaries. The list is not just a list but can also be used as a stack or a queue. In this article, I’ll explain everything you might want to know about Python lists:
- how to create lists,
- modify them,
- how to sort lists,
- loop over elements of a list with a for-loop or a list comprehension,
- how to slice a list,
- append to Python lists,
- … and more!
I’ve included lots of working code examples to demonstrate.
Table of Contents
- 1 How to create a Python list
- 2 Accessing Python list elements
- 3 Adding and removing elements
- 4 How to get List length in Python
- 5 Counting element occurrence in a list
- 6 Check if an item is in a list
- 7 Find the index of an item in a list
- 8 Loop over list elements
- 9 Python list to string
- 10 Sorting Python lists
- 11 Slicing
- 12 Reversing Python lists
- 13 Learn more about Python lists
How to create a Python list
Let’s start by creating a list:
my_list = [1, 2, 3] empty_list = []
Lists contain regular Python objects, separated by commas and surrounded by brackets. The elements in a list can have any data type and can be mixed. You can even create a list of lists. The following lists are all valid:
my_list = [1, "Erik", { 'age': 39 }] # This is a list with three lists inside game_board = [[], [], []]
Using the list() function
Python lists, like all Python data types, are objects. The list class is called ‘list’, and it has a lowercase L. If you want to convert another Python object to a list, you can use the list() function, which is actually the constructor of the list class itself. This function takes one argument: an iterable object.
So you can convert anything iterable into a list. E.g., you can materialize the range function into a list of actual values or convert a Python set or tuple into a list:
>>> list(range(1, 4)) [1, 2, 3] >>> list({1, 2, 2, 2, 3}) [1, 2, 3] >>> list( (1, 2, 3) ) [1, 2, 3]
Accessing Python list elements
To access an individual list element, you need to know its position. Since computers start counting at 0, the first element is in position 0, and the second element is in position 1, etcetera.
Here are a few examples:
>>> my_list = [1, 2, 3] >>> my_list[1] 2 >> my_list[0] 1 >> my_list[4] Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: list index out of range
As you can see, you can’t access elements that don’t exist. In this case, Python throws an IndexError exception, with the explanation ‘list index out of range.’ In my article on exceptions and the try and except statements, I’ve written about this subject in more depth in the section on best practices. I recommend you to read it.
Get the last element of a list
If you want to get elements from the end of the list, you can supply a negative value. In this case, we start counting at -1 instead of 0. E.g. to get the last element of a list, you can do this:
>>> my_list = [1, 2, 3] >>> my_list[-1] # get the last element 3 >>> my_list[-2] # get the 2nd last element 2
Accessing nested list elements
Accessing nested list elements is not that much different. When you access an element that is a list, that list is returned. So, to request an element in that list, you need to use a couple of brackets again:
>>> my_list = [[1, 2], [3, 4], [5, 6]] >>> my_list[0] [1, 2] >> my_list[0][0] 1 >>> my_list[2][1] 6
Adding and removing elements
Let’s see how we can add and remove data. There are several ways to remove data from a list. What you use depends on the situation. I’ll describe and demonstrate them all in this section.
Append to a Python list
List objects have several useful built-in methods, one of which is the append method. When calling append on a list, we append an object to the end of the list:
>>> my_list = [1, 2] >>> my_list.append('a') >>> my_list [1, 2, 'a'] >>> my_list.append(4) >>> my_list [1, 2, 'a', 4]
Combine or merge two lists
Another way of adding elements is adding all the elements from one list to the other. There are two ways to combine lists:
- ‘Add’ them together with the + operator.
- Add all elements of one list to the other with the extend method.
Here’s how you can add two lists together. The result is a new, third list:
>>> l1 = [1, 2] >>> l2 = [3, 4] >>> l3 = l1 + l2 >>> l3 [1, 2, 3, 4]
The original lists are kept intact. The alternative is to extend one list with another using the extend method:
>>> l1 = [1, 2] >>> l2 = [3, 4] >>> l1.extend(l2) >>> l1 [1, 2, 3, 4] >>> l2 [3, 4]
While l1 got extended with the elements of l2, l2 stayed the same. Extend appended all values from l2 to l1 and kept l2 as-is.
Pop items from a list
The pop() method removes and returns the last item by default unless you give it an index argument.
Here are a couple of examples that demonstrate both the default behavior and the behavior when given an index:
>>> my_list = [1, 2, 3, 4, 5] >>> my_list.pop() 5 >>> my_list.pop() 4 >>> my_list.pop(0) 1 >>> my_list [2, 3]
If you’re familiar with the concept of a stack, you can now build one using only the append and pop methods on a list!
Using del to delete items
There are multiple ways to delete or remove items from a list. While pop() returns the item that is deleted from the list, del
removes it without returning anything. In fact, you can delete any object, including the entire list, using del:
>>> my_list = [1, 2, 3, 4, 5] >>> del my_list[0] >>> my_list [2, 3, 4, 5] >>> del my_list[2] >>> my_list [2, 3, 5] >>> del my_list >>> my_list Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'my_list' is not defined
del
is not list-specific; it can delete any object in Python and does so recursively as well. Deleting things lets Python know it can free up the memory that was being used by the deleted object(s). For small programs, you don’t have to bother. However, if you load a lot of data in memory, it can be beneficial to explicitly delete the data you don’t need anymore.
Remove specific values from a Python list
If you want to remove a specific value from the list, use the remove() method. This method will remove the first occurrence of the given object in a list. Let’s demonstrate this by remove the number two from my_list
:
>>> my_list = [1, 2, 3, 2, 5] >>> my_list.remove(2) >>> my_list [1, 3, 2, 5] >>> my_list.remove(2) >>> my_list [1, 3, 5] >>> my_list.remove(2) Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: list.remove(x): x not in list
As you can see, repeated calls to remove will remove additional twos until none are left, in which case Python throws a ValueError exception.
Remove or clear all items from a Python list
To remove all items from a list, use the clear()
method:
>>> my_list = [1, 2, 3] >>> my_list.clear() >>> my_list []
Remove duplicates from a list
There is no particular function or method to remove duplicates from a list, but there are multiple tricks that we can use to do so anyway. The simplest, in my opinion, is using a Python set. Sets are collections of objects, like lists, but can only contain one of each element. More formally, sets are unordered collections of distinct objects.
By converting the list to a set and then back to a list again, we’ve effectively removed all duplicates:
>>> my_list = [1, 2, 2, 3, 5] >>> my_set = set(my_list) >>> my_set {1, 2, 3, 5} >>> list(my_set) [1, 2, 3, 5]
I’ve demonstrated this quite explicitly, but you usually want to use this more compact version:
>>> my_list = [1, 2, 2, 3, 5] >>> list(set(my_list)) [1, 2, 3, 5]
Since sets are very similar to lists, you may not have to convert them back into a list. If the set offers what you need, use it instead to prevent a double conversion, making your program a little bit faster and more efficient.
Replace items in a list
To replace list items, we assign a new value to a given list index, like so:
>>> my_list = [1, 2, 3, 4, 5] >>> my_list[0] = 400 >>> my_list [400, 2, 3, 4, 5]
How to get List length in Python
In Python, we use the len
function to get the length of objects. This is true for lists as well:
>>> my_list = [1, 2, 3, 4, 5] >>> len(my_list) 5
If you’re familiar with other programming languages, like Java, you might wonder why Python has a function for this. After all, it could have been one of the built-in methods of a list too, like my_list.len()
. This is because, in other languages, this often results in various ways to get an object’s length. E.g., some will call this function len
, others will call it length, and yet someone else won’t even implement the function but simply offer a public member variable. And this is exactly the reason why Python chose to standardize the naming of such a common operation!
Counting element occurrence in a list
Don’t confuse the count function with getting the list length; it’s totally different. The built-in count function counts occurrences of a particular value inside that list. Here’s an example:
>>> my_list = [1, 2, 1, 4, 1, 7] >>> my_list.count(1) 3 >>> my_list.count(4) 1
Since the number 1 occurs three times in the list, my_list.count(1)
returns 3.
Check if an item is in a list
To check if an item is in a list, use the following syntax:
>>> my_list = [1, 2] >>> if 1 in my_list: ... print("It's in the list") ... It's in the list
Find the index of an item in a list
We can find where an item is inside a list with the index method. For example, in the following list, the 4 is located at position 3 (remember that we start counting at zero):
>>> my_list = [1, 2, 3, 4, 5] >>> my_list.index(4) 3
The index method takes two optional parameters: start and stop. With these, we can continue looking for more of the same values. We don’t need to supply an end value if we provide a start value. Now, let’s find both 4’s in the list below:
my_list = [1, 2, 3, 4, 5, 4] print(my_list.index(4)) # Output: 3 # We know there's a 4 at position 3 so # let's continue our search from position 4 print(my_list.index(4, 4)) # Output: 5
If you want to do more advanced filtering of lists, you should read my article on list comprehensions.
Loop over list elements
A list is iterable, so we can use a for-loop over the elements of a list just like we can with any other iterable with the ‘for <element> in <iterable>’ syntax:
>>> my_list = [1, 2, 3, 4, 5] >>> for n in my_list: ... print(n) ... 1 2 3 4 5
Python list to string
In Python, you can convert most objects to a string with the str function:
>>> str([1, 'abc', 2.3]) "[1, 'abc', 2.3]"
If you’re interested, str is actually the Python string‘s base class and calling str()
constructs a new str object by calling the constructor of the str class. This constructor inspects the provided object and looks for a special method (also called dunder method) called __str__
. If it is present, this method is called. There’s nothing more to it.
If you create your own classes and objects, you can implement the __str__
function yourself to offer a printable version of your objects.
Sorting Python lists
To sort a Python list, we have two options:
- Use the built-in sort method of the list itself.
- Use Python’s built-in sorted() function.
Option one, the built-in method, offers an in-place sort. In other words, this function does not return anything. Instead, it modifies the list itself.
Option two returns a new list, leaving the original intact. Which one you use depends on the situation you’re in.
In-place list sort in ascending order
Let’s start with the simplest use-case: sorting in ascending order:
>>> my_list = [10, 2, 5, 4, 2] >>> my_list.sort() >>> my_list [2, 2, 4, 5, 10]
In-place list sort in descending order
We can call the sort method with a reverse parameter. If this is set to True, sort reverses the order:
>>> my_list = [10, 2, 5, 4, 2] >>> my_list.sort(reverse=True) >>> my_list [10, 5, 4, 2, 2]
Using sorted()
The following example demonstrates how to sort lists in ascending order, returning a new list with the result:
>>> my_list = [10, 2, 5, 4, 2] >>> sorted(my_list) [2, 2, 4, 5, 10] >>> my_list [10, 2, 5, 4, 2]
As you can see from the last statement, the original list is unchanged. Let’s do that again, but now in descending order:
>>> my_list = [10, 2, 5, 4, 2] >>> sorted(my_list, reverse=True) [10, 5, 4, 2, 2] >>> my_list [10, 2, 5, 4, 2]
Unsortable lists
We can not sort all lists since Python can not compare all types with each other. For example, we can sort a list of numbers, like integers and floats, because they have a defined order. We can sort a list of strings as well since Python is able to compare strings too.
However, lists can contain any type of object, and we can’t compare completely different objects, like numbers and strings, to each other. In such cases, Python throws a TypeError
:
>>> my_mixed_list = [1, 'a', 2, 'B'] >>> my_mixed_list.sort() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: '<' not supported between instances of 'str' and 'int'
Although the error might look cryptic, it’s only logical when you know what’s going on. To sort a list, Python needs to compare the objects to each other. So in its sorting algorithm, at some point, it checks if ‘a’ < 1, hence the error: '<' not supported between instances of 'str' and 'int'
.
Slicing
Sometimes you need to get parts of a list. Python has a powerful syntax to do so, called slicing, and it makes working with lists much easier than other programming languages. Slicing works on Python lists and all other sequence types, like strings, tuples, and ranges.
The slicing syntax is as follows:
my_list[start:stop:step]
A couple of notes:
start
is the first element position to includestop
is exclusive, meaning that the element at positionstop
won’t be included.step
is the step size. more on this later.start
,stop
, andstep
are all optional.- Negative values can be used too.
To explain how slicing works, it’s best to just look at examples, and try for yourself, so that’s what we’ll do:
>>> my_list = [1, 2, 3, 4, 5, 6, 7, 8] >>> my_list[0:3] # get the first three elements of a list [1, 2, 3] >>> my_list[:3] # start is 0 by default [1, 2, 3] >>> my_list[4:] # skip the first 4 elements [5, 6, 7, 8]
The step value
The step value in a slice is one by default. A step size of one means all elements are considered for the slice. If you increase the step size, you can step over elements. E.g., a step size of two means on each step, one element is skipped over. Let’s try this:
>>> my_list = [1, 2, 3, 4, 5, 6, 7, 8] >>> my_list[::2] # skip one each time [1, 3, 5, 7]
Going backward
Like with list indexing, we can also supply negative numbers with slicing. Here’s a little ASCII art to show you how counting backward in a list works:
my_list = [1 , 2, 3, 4, 5, 6] -6 -5 -4 -3 -2 -1 (these are the index numbers)
Just remember that you need to set a negative step size to go backward:
>>> my_list = [1, 2, 3, 4, 5, 6] >>> my_list[-1:-3:-1] [6, 5]
Reversing Python lists
There are three methods you can use to reverse a list in Python:
- An in-place reverse, using the built-in reverse method that every list has natively
- Using list slicing with a negative step size results in a new list
- Create a reverse iterator, with the
reversed()
function
In the following code crumb, I demonstrate all three. They are explained in detail in the following sections:
Using the built-in reverse method
The list.reverse()
method does an in-place reverse, meaning it reorders the list. In other words, the method does not return a new list object, with a reversed order. Here’s how to use reverse()
:
>>> lst = [1, 2, 3, 4] >>> lst.reverse() >>> lst [4, 3, 2, 1] >>> lst.reverse() >>> lst [1, 2, 3, 4]
Reverse a list with list slicing
Although you can reverse a list with the list.reverse()
method that every list has, you can do it with list slicing too, using a negative step size of -1. The difference is that list slicing results in a new, second list. It keeps the original list intact:
>>> lst = [1, 2, 3, 4] >>> lst[::-1] [4, 3, 2, 1] >>> lst [1, 2, 3, 4]
Creating a reverse iterator
Finally, you can use the reversed()
built-in function, which creates an iterator that returns all elements of the given iterable (our list) in reverse. This method is quite cheap in terms of CPU and memory usage. All it needs to do is walk backward over the iterable object. It doesn’t need to move around data, and it doesn’t need to reserve extra memory for a second list. So if you need to iterate over a (large) list in reverse, this should be your choice.
Here’s how you can use this function. Keep in mind that you can only use the iterator once but that it’s cheap to make a new one:
>>> lst = [1, 2, 3, 4] >>> rev = reversed(lst) >>> rev <list_reverseiterator object at 0x0000023DB96A25C0> >>> for i in rev: ... print(i) ... 4 3 2 1
Learn more about Python lists
Because there’s a lot to tell about list comprehensions, I created a dedicated article for the topic. A Python list comprehension is a language construct that we use to efficiently create a list based on an existing list (without using for-loops).
Some other resources you might like:
- The official Python docs about lists.
- If you are interested in the internals, lists are often implemented internally as a linked list.
- Python also has arrays, which are very similar and the term will be familiar to people coming from other programming languages. They are more efficient at storing data, but they can only store one type of data.