Complete guide to Python's reversed function covering sequences, custom objects, and practical examples of reverse iteration.
Last modified April 11, 2025
This comprehensive guide explores Python’s reversed function, which returns a reverse iterator for sequences. We’ll cover built-in sequences, custom objects, and practical examples of reverse iteration.
The reversed function returns a reverse iterator object that accesses elements in reverse order. It works with any object that implements reversed or supports sequence protocol (len and getitem).
Key characteristics: returns an iterator (not a list), preserves original sequence, works with strings, lists, tuples, and custom sequences. It’s memory efficient as it doesn’t create a new sequence.
Here’s simple usage with different sequence types showing how reversed handles lists, tuples, and strings.
basic_reversed.py
numbers = [1, 2, 3, 4, 5] print(list(reversed(numbers))) # [5, 4, 3, 2, 1]
colors = (‘red’, ‘green’, ‘blue’) print(tuple(reversed(colors))) # (‘blue’, ‘green’, ‘red’)
text = “hello” print(’’.join(reversed(text))) # “olleh”
This example shows reversed with different sequence types. Note that we convert the iterator to a concrete type (list, tuple, string) for display. The original sequences remain unchanged.
For strings, we use join to combine the reversed characters back into a string. The reversed function works with any sequence that supports indexing.
You can make custom objects work with reversed by implementing the reversed special method. This example creates a CountDown class.
custom_reversed.py
class CountDown: def init(self, start): self.start = start
def __reversed__(self):
n = 1
while n <= self.start:
yield n
n += 1
def __iter__(self):
n = self.start
while n > 0:
yield n
n -= 1
print(“Normal iteration:”) for x in CountDown(5): print(x) # 5, 4, 3, 2, 1
print(“Reversed iteration:”) for x in reversed(CountDown(5)): print(x) # 1, 2, 3, 4, 5
The CountDown class implements both iter and reversed. Normal iteration counts down, while reversed iteration counts up.
This demonstrates how to customize reverse iteration behavior for your objects. The reversed method should return an iterator.
The reversed function works efficiently with range objects, creating a reverse iterator without generating all numbers in memory.
range_reversed.py
for i in range(5): print(i) # 0, 1, 2, 3, 4
for i in reversed(range(5)): print(i) # 4, 3, 2, 1, 0
large_range = reversed(range(1, 1000001)) print(next(large_range)) # 1000000 print(next(large_range)) # 999999
This example shows how reversed works with range objects. The reverse iteration is memory efficient, especially with large ranges.
The range object implements reversed specially to provide this efficient reverse iteration without storing all numbers.
The reversed function raises TypeError when used with non-sequence types. This example shows proper error handling.
errors.py
try: print(list(reversed(42))) except TypeError as e: print(f"Error: {e}") # ‘int’ object is not reversible
class NoReverse: pass
try: print(list(reversed(NoReverse()))) except TypeError as e: print(f"Error: {e}") # ‘NoReverse’ object is not reversible
These examples demonstrate reversed’s behavior with unsupported types. Non-sequence objects and objects without reversed or sequence protocol raise TypeError.
To make a class work with reversed, implement either reversed or the sequence protocol as shown earlier.
This example compares reversed performance with alternative methods for reverse iteration.
performance.py
import timeit
def test_reversed(): return list(reversed([1, 2, 3, 4, 5]))
def test_slice(): return [1, 2, 3, 4, 5][::-1]
def test_manual(): lst = [1, 2, 3, 4, 5] return [lst[i] for i in range(len(lst)-1, -1, -1)]
print(“reversed():”, timeit.timeit(test_reversed, number=1000000)) print(“slice:”, timeit.timeit(test_slice, number=1000000)) print(“manual:”, timeit.timeit(test_manual, number=1000000))
This benchmarks different reverse iteration methods. reversed is generally fastest for iteration. Slicing creates a new list but is fast for small sequences.
The manual approach is slower and less readable, demonstrating why reversed is preferred for iteration scenarios.
Use for iteration: Prefer reversed over slicing when you only need to iterate
Implement reversed: For custom sequence types that support reverse iteration
Consider slicing: When you need a reversed copy of the sequence
Handle errors: Catch TypeError when input type is uncertain
Document behavior: Clearly document reversed implementation
My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.
List all Python tutorials.