Reversing a list is a common operation in Python programming.
For example, imagine you had a sorted list of customer names that your program displays in alphabetical (A-Z) order. Some of your users would like to view the customer list so that the names are in reverse alphabetical order. How are you going to flip the order of this existing list on its head? Or in other words:
What’s the best way to reverse the order of a list in Python?
In this article you’ll see three different ways to achieve this result in “plain vanilla” Python, meaning without the use of any third-party libraries:
- Reversing a list in-place with the
- Using the “
[::-1]” list slicing trick to create a reversed copy
- Creating a reverse iterator with the
All examples I’m using here will be based on the following list object containing the numbers 1 through 5:
# You have this: [1, 2, 3, 4, 5] # And you want that: [5, 4, 3, 2, 1]
Ready? Let’s reverse some lists together!
Option #1: Reversing a List In-Place With the
Every list in Python has a built-in
reverse() method you can call to reverse the contents of the list object in-place. Reversing the list in-place means won’t create a new list and copy the existing elements to it in reverse order. Instead, it directly modifies the original list object.
Here’s an example:
>>> mylist = [1, 2, 3, 4, 5] >>> mylist [1, 2, 3, 4, 5] >>> mylist.reverse() None >>> mylist [5, 4, 3, 2, 1]
As you can see, calling
None, but modified the original list object. This implementation was chosen deliberately by the developers of the Python standard library:
reverse()method modifies the sequence in place for economy of space when reversing a large sequence. To remind users that it operates by side effect, it does not return the reversed sequence. (Source: Python 3 Docs)
In-place reversal has some benefits and some downsides. On the plus side, it’s a fast operation—shuffling the list elements around doesn’t require much extra memory, as we’re not creating a full copy of the list.
However, reversing a list in-place overwrites the original sort order. This could be a potential downside. (Of course, to restore the original order you coud simply reverse the same list again.)
From a code readability standpoint, I like this approach. The syntax is clear and easy to understand, even for developers new to Python or someone who comes from another language background.
Option #2: Using the “
[::-1]” Slicing Trick to Reverse a Python List
Python’s list objects have an interesting feature called slicing. You can view it as an extension of the square-brackets indexing syntax. It includes a special case where slicing a list with “
[::-1]” produces a reversed copy:
>>> mylist [1, 2, 3, 4, 5] >>> mylist[::-1] [5, 4, 3, 2, 1]
Reversing a list this way takes up a more memory compared to an in-place reversal because it creates a (shallow) copy of the list. And creating the copy requires allocating enough space to hold all of the existing elements.
Note that this only creates a “shallow” copy where the container is duplicated, but not the individual list elements. Instead of duplicating the list elements themselves, references to the original elements are reused in the new copy of the container. If the elements are mutable, modifying an element in the original list will also be reflected in the copy.
The biggest downside to reversing a list with the slicing syntax is that it uses a more advanced Python feature that some people would say is “arcane.” I don’t blame them—list slicing is fast, but also a little difficult to understand the first time you encounter its quirky syntax.
When I’m reading Python code that makes use of list slicing I often have to slow down and concentrate to “mentally parse” the statement, to make sure I understand what’s going on. My biggest gripe here is that the “
[::-1]” slicing syntax does not communicate clearly enough that it creates a reversed copy of the original list.
Using Python’s slicing feature to reverse a list is a decent solution, but it can be a difficult to read to the uninitiated. Be sure to remember the wise words of master Yoda: With great power, great responsibility comes 🙂
Sidebar: How does list slicing work in Python?
Reversing a list this way takes advantage of Python’s “slicing” syntax that can be used to do a number of interesting things. List slicing uses the “
” indexing syntax with the following “
>>> mylist[start:end:step] >>> mylist [1, 2, 3, 4, 5] >>> mylist[1:3] [2, 3]
Adding the “
[1:3]” index tells Python to give us a slice of the list from index 1 to index 2. To avoid off-by-one errors it’s important to remember that the upper bound is exclusive—this is why we only got
[2, 3] as the sub-list from the
All of the indexes are optional, by the way. You can leave them out and, for example, create a full (shallow) copy of a list like this:
>>> mylist[:] [1, 2, 3, 4, 5]
The step parameter, sometimes called the stride, is also interesting. Here’s how you can create a copy of a list that only includes every other element of the original:
>>> mylist[::2] [1, 3, 5]
Earlier we used the same “step” trick to reverse a list using slicing:
>>> mylist[::-1] [5, 4, 3, 2, 1]
We ask Python to give us the full list (
::), but to go over all of the elements from back to front by setting the step to -1. Pretty neat, eh?
Option #3: Creating a Reverse Iterator With the
reversed() Built-In Function
Reversing a list using reverse iteration with the
reversed() built-in is another option. It neither reverses a list in-place, nor does it create a full copy. Instead we get a reverse iterator we can use to cycle through the elements of the list in reverse order:
>>> mylist = [1, 2, 3, 4, 5] >>> for item in reversed(mylist): ... print(item) 5 4 3 2 1 >>> mylist >>> [1, 2, 3, 4, 5]
reversed() does not modify the original list. In fact all we get is a “view” into the existing list that we can use to look at all the elements in reverse order. This is a powerful technique that takes advantage of Python’s iterator protocol.
So far, all we did was iterating over the elements of a list in reverse order. But how can you create a reversed copy of a list using Python’s
>>> mylist = [1, 2, 3, 4, 5] >>> list(reversed(mylist)) [5, 4, 3, 2, 1]
Notice how I’m calling the
list() constructor on the result of the
Using the list constructor built-in keeps iterating until the (reverse) iterator is exhausted, and puts all the elements fetched from the iterator into a new list object. And this gives us the desired result: A reversed shallow copy of the original list.
I really like this reverse iterator approach for reversing lists in Python. It communicates clearly what is going on, and even someone new to the language would intuitively understand we’re creating a reversed copy of the list. And while understanding how iterators work at a deeper level is helpful, it’s not absolutely necessary to use this technique.
Summary: Reversing Lists in Python
List reversal is a fairly common operation in programming. In this tutorial we covered three different approaches for reversing a list or array in Python. Let’s do a quick recap on each of those approaches before I’ll give you my final verdict on which option I recommend the most:
Python lists can be reversed in-place with the
list.reverse() method. This is a great option to reverse the order of a list (or any mutable sequence) in Python. It modifies the original container in-place which means no additional memory is required. However the downside is, of course, that the original list is modified.
>>> lst = [1, 2, 3, 4, 5] >>> lst.reverse() >>> lst [5, 4, 3, 2, 1]
- Reverses the list in-place
- Fast, doesn’t take up extra memory
- Modifies the original list
Option 2: List Slicing Trick
You can use Python’s list slicing syntax to create a reversed copy of a list. This works well, however it is slightly arcane and therefore not very Pythonic, in my opinion.
>>> lst = [1, 2, 3, 4, 5] >>> lst[::-1] [5, 4, 3, 2, 1]
- Creates a reversed copy of the list
- Takes up memory but doesn’t modify the original
reversed() function allows you to create a reverse iterator for an existing list or sequence object. This is a flexible and clean solution that relies on some advanced Python features—but it remains readable due to the clear naming of the
>>> lst = [1, 2, 3, 4, 5] >>> list(reversed(lst)) [5, 4, 3, 2, 1]
- Returns an iterator that returns elements in reverse order
- Doesn’t modify the original
- Might need to be converted into a list object again
If you’re wondering what the “best” way is to reverse a list in Python my answer will be: “It depends.” Personally, I like the first and third approach:
list.reverse()method is fast, clear and speaks for itself. Whenever you have a situation where you want to reverse a list in-place and don’t want a copy and it’s okay to modify the original, then I would go with this option.
If that isn’t possible, I would lean towards the reversed iterator approach where you call
reversed()on the list object and you either cycle through the elements one by one, or you call the
list()function to create a reversed copy. I like this solution because it’s fast and clearly states its intent.
I don’t like the list slicing trick as much. It feels “arcane” and it can be difficult to see at a glance what’s going on. I try to avoid using it for this reason.
Note that there are other approaches like implementing list reversal from scratch or reversing a list using a recursive algorithm that are common interview questions, but not very good solutions for Python programming in the “real world.” That’s why I didn’t cover them in this tutorial.
If you’d like to dig deeper into the subject, be sure to watch my YouTube tutorial on list reversal in Python. It’s also embedded at the top of the article. Happy Pythoning!