Python
Reverse Order
List Traversal
Programming
Duplicate Content

Traverse a list in reverse order in Python

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

Python gives you several clean ways to traverse a list in reverse order. The best choice depends on whether you want a lazy iterator, a copied reversed list, original indices, or an in-place mutation. Most code should start with reversed, because it is readable and avoids unnecessary copying.

Use reversed for Read-Only Reverse Iteration

The simplest way to walk through a list from the end to the beginning is reversed.

python
values = [10, 20, 30, 40]
for value in reversed(values):
    print(value)

reversed(values) returns an iterator, so it does not create a new list. That makes it a good default when you only need to iterate once.

It also leaves the original list unchanged, which is usually what you want in code that reads data rather than mutating it.

Use Slicing When You Need a Reversed Copy

If you need to reuse the reversed order more than once or pass it to an API that expects a real list, slicing is appropriate.

python
1values = [10, 20, 30, 40]
2reversed_copy = values[::-1]
3
4print(reversed_copy)
5print(values)

The tradeoff is memory. Slicing creates a new list, so it is more expensive than reversed for large collections.

Use this when the reversed result is itself data you need to keep, not just a temporary iteration order.

Use an Index Loop When Positions Matter

Sometimes you need the original index as well as the value. In that case, iterate over indices explicitly.

python
1letters = ["a", "b", "c", "d"]
2
3for i in range(len(letters) - 1, -1, -1):
4    print(i, letters[i])

This is useful when reverse traversal is tied to index-based logic such as deleting items by position or comparing neighboring elements.

Be careful with the range bounds. The start is len(list) - 1, and the stop is -1 so that index 0 is still included.

Reverse In Place Only When Mutation Is Intended

Lists also have a .reverse() method.

python
items = [1, 2, 3, 4]
items.reverse()
print(items)

This mutates the original list. It is memory-efficient, but it changes shared state. Use it only when that mutation is part of the intended behavior.

If some other part of the program still expects the original order, .reverse() is the wrong tool.

Choosing the Right Technique

A useful rule of thumb is:

  • use reversed for simple iteration
  • use slicing for a reusable reversed copy
  • use an index loop when you need positions
  • use .reverse() only when you intentionally want to mutate the list

This keeps the code honest about memory use and side effects.

For example, log processing from newest to oldest is often a perfect fit for reversed, while building a reversed snapshot for later use is a better fit for slicing.

Reverse Traversal in Real Code

Here is a small example where reverse traversal is part of actual logic rather than just printing values.

python
1history = [
2    {"status": "created"},
3    {"status": "running"},
4    {"status": "failed"},
5]
6
7last_non_running = None
8for event in reversed(history):
9    if event["status"] != "running":
10        last_non_running = event
11        break
12
13print(last_non_running)

This reads naturally: start from the end and stop when the first relevant item is found.

Common Pitfalls

A common mistake is using .reverse() when the original list still needs to be preserved. That can create subtle bugs because the mutation happens in place.

Another issue is assuming slicing is lazy. It is not. values[::-1] allocates a new list.

Off-by-one errors are also common in manual index loops. If the stop value is wrong, the first element can be skipped accidentally.

Finally, avoid turning every reverse traversal into an index loop. If you only need the values, reversed is usually clearer.

Summary

  • Use reversed for clean, memory-efficient reverse iteration.
  • Use slicing when you need a separate reversed list.
  • Use range(len(values) - 1, -1, -1) when you need original indices.
  • Use .reverse() only when in-place mutation is intended.
  • Choose the approach based on memory needs, mutation requirements, and readability.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.