Complete guide to Python's __reversed__ method covering reverse iteration, custom sequences, and practical examples.
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.
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.
Here’s a simple implementation showing how reversed works with a custom sequence class. The method returns a reverse iterator.
basic_reversed.py
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.
For more control, you can create a custom reverse iterator class instead of using the built-in reversed().
custom_iterator.py
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.
reversed is particularly useful for data structures where reverse iteration isn’t as simple as counting backwards through indices.
linked_list.py
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.
For sequences that support slicing, reversed can leverage this for a concise implementation.
slice_reversed.py
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.
For more complex collections, reversed can implement custom reverse iteration logic that doesn’t rely on indices.
custom_collection.py
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.
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
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.