Background:
Sequences are one of the oldest and most fundamental concepts in Python. Classic examples include lists (list), strings (str), and tuples (tuple). A special protocol has been defined for interacting with sequences: you need to implement the __getitem__ and __len__ methods. This allows an object to behave "like a sequence"—supporting indexing, slicing, loop operations, and even certain standard functions.
Problem:
Without proper implementation of these methods, a user-defined class will not work with indexing operations, for-loops, or functions like len(). Often, beginner developers implement only one of the methods, neglect exception handling, and do not support slicing, leading to incorrect or unexpected behavior.
Solution:
You need to implement the __getitem__(self, key) method to support indexing and slicing, as well as __len__(self) for working with the len() function and proper iterability. To support slicing, you must differentiate the type of key in __getitem__ and correctly handle slice objects.
Code Example:
def is_even(n): return n % 2 == 0 class EvenSequence: def __init__(self, size): self.size = size def __getitem__(self, index): if isinstance(index, slice): return [x for x in range(self.size)[index] if is_even(x)] if index < 0 or index >= self.size: raise IndexError('Index out of bounds') return index if is_even(index) else None def __len__(self): return self.size
Key Features:
Can we rely solely on the getitem method for the object to work as a sequence?
Partially. If only __getitem__ is implemented, the object can be iterated over via for and indexed, but len() will not work.
Code Example:
class SeqOnlyGetitem: def __getitem__(self, index): if index >= 10: raise IndexError return index * 2 s = SeqOnlyGetitem() for x in s: print(x) # Works (iterable) # print(len(s)) # This raises TypeError
How to handle negative indices and what happens if they're not considered?
Negative indices are a key feature of sequences in Python. If they're not handled, the object behaves unexpectedly for the user.
class NegIndex: def __init__(self, data): self.data = data def __getitem__(self, index): if index < 0: index += len(self.data) return self.data[index]
Is it necessary to implement contains or iter for your Sequence class?
Not necessarily. If __getitem__ and __len__ are implemented, the in operator will work, and for will use them for iteration. Implementing these methods directly is usually not required, but can improve performance.
A developer implemented only getitem for their class for positive indices only. The module passed part of the unit tests, but in real use, attempts to access non-existing or negative indices broke everything.
Pros:
Cons:
The team implemented both methods (getitem and len), considered slicing, negative indices, and raised correct exceptions. The final class worked in all standard Python cases.
Pros:
Cons: