Note “types implementing __getitem__ but not __iter__ are” NOT “assumed to be “infinite lazy sequences” by default.”
class FiniteGetItemExample:
def __getitem__(self, key):
if key in range(10):
return key
else:
raise IndexError
list(FiniteGetItemExample())
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
About __getitem__ / __iter__ connection: many people coming from other languages (Java and its kin) code iteration unpythonically as a loop over getting items. The default implementation eases that path (no idea if that’s the reason it was included in paleo-Python).