How to loop backwards in python?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Python provides several ways to loop backwards through a sequence: reversed() for any iterable, range(start, stop, step) with a negative step for index-based iteration, and slice notation [::-1] for creating a reversed copy. The choice depends on whether you need the index, whether you want to avoid creating a copy, and whether you are iterating over a list, string, or range of numbers.
Using reversed()
reversed() returns a reverse iterator without creating a copy:
reversed() works with any sequence (list, tuple, string, range) and any object that implements __reversed__() or __len__() and __getitem__():
Using range() with Negative Step
For iterating over indices in reverse:
The range(start, stop, step) parameters for backwards iteration:
start: the first value (inclusive)stop: the end value (exclusive) — usually-1to include index0step:-1for stepping backwards by one,-2for every other, etc.
Using Slice Notation [::-1]
Slice notation creates a reversed copy:
Unlike reversed(), slicing creates a new list in memory. For large sequences, reversed() is more memory-efficient.
Using enumerate with reversed
When you need both the index and value:
Reversing and Iterating a Dictionary
Dictionaries maintain insertion order in Python 3.7+, and reversed() on dicts was added in Python 3.8.
Modifying a List While Iterating Backwards
Backwards iteration is safe for removing elements because it does not shift unvisited indices:
Performance Comparison
| Method | Memory | Speed | Creates Copy |
reversed() | O(1) | Fast | No |
[::-1] | O(n) | Fast | Yes |
range(n-1, -1, -1) | O(1) | Moderate | No |
Common Pitfalls
- Using
reversed()on a generator:reversed()requires a sequence with a known length. Passing a generator or iterator raisesTypeError: argument to reversed() must be a sequence. Convert to a list first:reversed(list(gen)). - Off-by-one in
range()stop value:range(5, 0, -1)produces5, 4, 3, 2, 1— it does not include0. To include0, userange(5, -1, -1)which gives5, 4, 3, 2, 1, 0. - Modifying a list while iterating forward: Removing elements during forward iteration shifts indices and skips elements. Iterate backwards with
range(len(lst)-1, -1, -1)or use list comprehension[x for x in lst if condition]instead. - Slicing large sequences:
data[::-1]creates a full copy of the list, doubling memory usage. For million-element lists, usereversed()which creates only an iterator. - Expecting
reversed()to return a list:reversed()returns an iterator, not a list. Callingreversed(data)[0]raisesTypeError. Wrap inlist()if you need random access:list(reversed(data))[0].
Summary
reversed()is the most Pythonic way — creates a memory-efficient reverse iteratorrange(n-1, -1, -1)is best when you need the index for backwards traversal[::-1]creates a reversed copy — convenient but uses O(n) extra memory- Use backwards iteration when removing elements from a list to avoid index-shifting bugs
reversed()works on dicts in Python 3.8+- Prefer
reversed()over[::-1]for large sequences to save memory

