Reversing Lists

Concepts covered: Slicing

Many lists are stored oldest first, because that's the order items arrive in, and read newest first, because the latest entries matter most. Python offers 3 ways to flip the order. They give back different things, and choosing the wrong one usually shows up as a None or as a list you didn't mean to change.

reverse() flips the list itself

letters = ["a", "b", "c", "d", "e"]
print("Before:", letters)

letters.reverse()
print("After:", letters)
Before: ['a', 'b', 'c', 'd', 'e']
After: ['e', 'd', 'c', 'b', 'a']

letters.reverse() reorders the items inside letters: after the call, the same list holds e first and a last. No new list is created, and the method returns None, the value Python uses for no result.

events = ["login", "search", "add_to_cart", "checkout"]

result = events.reverse()
print(result)
print(events)

events = events.reverse()
print(events)

Output:

None
['checkout', 'add_to_cart', 'search', 'login']
None

The last 2 lines show a common bug. events.reverse() flips the list. The assignment then replaces events with None, which is what the method returns, so the data is gone. The next line that indexes events fails with TypeError: 'NoneType' object is not subscriptable. Call reverse() on a line of its own and keep using the same name.

[::-1] builds a reversed copy

events = ["login", "search", "add_to_cart", "checkout"]

newest_first = events[::-1]
print(newest_first)
print(events)
print(events[-1:-3:-1])
print(events[2::-1])

Output:

['checkout', 'add_to_cart', 'search', 'login']
['login', 'search', 'add_to_cart', 'checkout']
['checkout', 'add_to_cart']
['add_to_cart', 'search', 'login']

A step of -1 walks from the end toward the front. With both ends left out, [::-1] visits every item backwards and returns a new list, leaving events in its original order. With a negative step the defaults swap: an empty start means the last item and an empty stop means past the first. So events[2::-1] starts at position 2 and walks back to the front, and events[-1:-3:-1] takes positions -1 and -2, stopping before -3.

reversed() for looping backwards

events = ["login", "search", "add_to_cart", "checkout"]

for event in reversed(events):
    print(event)

print(list(reversed(events)))
print(events)

Output:

checkout
add_to_cart
search
login
['checkout', 'add_to_cart', 'search', 'login']
['login', 'search', 'add_to_cart', 'checkout']

reversed(events) hands out the items from last to first, one per pass of a for loop, without building a reversed list and without changing events. It reads the original list as the loop runs, which makes it the cheapest choice when you only walk backwards once. Printing it directly shows a description of an object instead of the items; wrap it in list() when you need a real list.

ToolGives backOriginal listUse it when
`events.reverse()`NoneReorderedThe list should stay flipped from now on
`events[::-1]`A new reversed listUnchangedYou need both orders, or a backwards slice
`reversed(events)`Items for a loop, last firstUnchangedYou loop backwards once

What does this program print?

scores = [10, 20, 30, 40, 50]
flipped = scores[::-1]
scores.reverse()
print(flipped == scores, flipped is scores)

About this lesson

This section is part of the Lists: Intermediate lesson on DataDriven, the home of data engineering. Lessons cover SQL, Python, Spark, data modeling and pipeline architecture, and each section pairs its explanation with worked examples and practice you run as you go.