Python __reversed__ Method
Last modified April 8, 2025
This comprehensive guide explores Python's __reversed__
method, the
special method that enables reverse iteration over sequences. We'll cover basic
usage, custom sequence implementation, and practical examples.
Basic Definitions
The __reversed__
method returns an iterator that yields items in
reverse order. It is called by the built-in reversed()
function.
Key characteristics: it should return an iterator object, is optional for sequence types, and provides more efficient reverse iteration than slicing for some types. It enables custom reverse iteration behavior.
Basic __reversed__ Implementation
Here's a simple implementation showing how __reversed__
works with
a custom sequence class. The method returns a reverse iterator.
class MySequence: def __init__(self, data): self.data = data def __len__(self): return len(self.data) def __getitem__(self, index): return self.data[index] def __reversed__(self): return reversed(self.data) seq = MySequence([1, 2, 3, 4, 5]) for item in reversed(seq): print(item)
This example shows a sequence class implementing __reversed__
by
delegating to the built-in reversed()
function. The output would
print numbers from 5 down to 1.
The class also implements __len__
and __getitem__
,
making it a proper sequence. __reversed__
enhances its capabilities.
Custom Reverse Iterator
For more control, you can create a custom reverse iterator class instead of
using the built-in reversed()
.
class ReverseIterator: def __init__(self, sequence): self.sequence = sequence self.index = len(sequence) def __iter__(self): return self def __next__(self): if self.index == 0: raise StopIteration self.index -= 1 return self.sequence[self.index] class MySequence: def __init__(self, data): self.data = data def __len__(self): return len(self.data) def __getitem__(self, index): return self.data[index] def __reversed__(self): return ReverseIterator(self) seq = MySequence([10, 20, 30, 40]) for item in reversed(seq): print(item)
This implementation shows a dedicated ReverseIterator
class that
handles the reverse iteration logic. It maintains an index that counts down.
The iterator implements both __iter__
and __next__
,
making it a proper iterator. This approach offers maximum flexibility.
Reversing a Linked List
__reversed__
is particularly useful for data structures where
reverse iteration isn't as simple as counting backwards through indices.
class Node: def __init__(self, value, next_node=None): self.value = value self.next = next_node class LinkedList: def __init__(self): self.head = None def append(self, value): if not self.head: self.head = Node(value) else: current = self.head while current.next: current = current.next current.next = Node(value) def __iter__(self): current = self.head while current: yield current.value current = current.next def __reversed__(self): values = list(self) return reversed(values) lst = LinkedList() lst.append(1) lst.append(2) lst.append(3) for item in reversed(lst): print(item)
This linked list implementation shows how __reversed__
can work with
non-indexed sequences. It converts the list to a Python list first.
For large linked lists, a more efficient approach would be to implement a proper reverse iterator that traverses the list without creating a temporary list.
Reversing with Slice Syntax
For sequences that support slicing, __reversed__
can leverage this
for a concise implementation.
class MyRange: def __init__(self, start, stop): self.start = start self.stop = stop def __len__(self): return max(0, self.stop - self.start) def __getitem__(self, index): if index < 0: index += len(self) if 0 <= index < len(self): return self.start + index raise IndexError("Index out of range") def __reversed__(self): return self[::-1] r = MyRange(1, 6) for num in reversed(r): print(num)
This range-like class implements __reversed__
using Python's slice
syntax. The [::-1]
slice creates a reverse view of the sequence.
The slice approach is concise but may not be the most efficient for very large sequences, as it creates a new sequence object in memory.
Reversing a Custom Collection
For more complex collections, __reversed__
can implement custom
reverse iteration logic that doesn't rely on indices.
class TreeNode: def __init__(self, value): self.value = value self.children = [] def add_child(self, node): self.children.append(node) class Tree: def __init__(self, root): self.root = root def __reversed__(self): def traverse(node): for child in reversed(node.children): yield from traverse(child) yield node.value return traverse(self.root) root = TreeNode(1) child1 = TreeNode(2) child2 = TreeNode(3) root.add_child(child1) root.add_child(child2) child1.add_child(TreeNode(4)) child1.add_child(TreeNode(5))) tree = Tree(root) for value in reversed(tree): print(value)
This tree structure implements reverse depth-first traversal using
__reversed__
. It recursively yields children in reverse order.
The implementation uses a nested generator function to handle the recursive traversal. This pattern is common for complex data structures.
Best Practices
- Return an iterator: Ensure __reversed__ returns an iterator object
- Maintain consistency: Reversed order should match expectations
- Consider efficiency: Optimize for large sequences
- Document behavior: Clearly document the reversal order
- Implement both directions: Provide __iter__ and __reversed__
Source References
Author
List all Python tutorials.