Iterable is a Python protocol that describes all objects that can be traversed. A class whose functionality includes keeping or organizing multiple elements should implement the Iterable interface. By defining functions common to all Iterables, such as
__getitem__, a class can gain access to traversal functionality that can be seen in the built-in sequence data types lists, tuples, and dictionaries. Iterable should not be confused with Iterator, which is a different protocol that allows users to access elements of a sequence one at a time.
Types of Iterables
Built in Iterables
The Python language contains common Iterables such as the list object ([3, 4, 3]) and the range object (range(4, 20). Users will frequently use these built in Iterables to traverse through a sequence of items or a list of numbers in a compact and readable manner. The String object is also a default Iterable, as it is simply a sequence of characters.
User defined Iterables
Any object can be an Iterable if the class implements the
__iter__() function, or
__getitem__(index) function. When a class includes the
__iter__(), it tells Python that every object of this class will be an Iterable. Therefore the function
__iter__() usually just returns
__getitem__(index) function must define a process of sequencing through the iterable to reach an element at a specified index, then returning that element. Lastly the
__len__ function must count the number of elements in the iterable and return that total.
Implementing and Using Iterables
As stated in the previous section, implementing an Iterable requires the definition of either
__getitem__(index). In this case,
__getitem__(index) is sufficient for satisfying the iterable interface.
class Counter: def __init__(self, low, high): self.current = low self.high = high # Not necessary for the iterable interface, but useful to have def __len__(self): return self.high - self.low + 1 # This function helps satisfy the iterable interface def __getitem__(self, index): if self.low + index > self.high: raise IndexError("Counter index out of range") return self.low + index >>> a = Counter(1, 5) >>> for num in a: ... print(num) 1 2 3 4 5 >>> len(a) 5 >>> 4 in a True >>> 6 in a False
Counter example, we define
__getitem__. The len function requires some thinking. For the purposes of
Counter, the number of elements in the Iterable is sipmly the largest input number take away the smallest, then add 1. To get the number at the input index, we simply have to return low + index (low + 0 = low, low + 1 = the next number, and so on). Different classes, of course, will require different implementations of these common functions. To prevent the counter from going on infinitely, we can raise an
IndexError. This, for instance, allows the for loop to terminate.
How are Iterables and their functions used?
__len function is not directly used; instead, it is implemented more commonly as len(). When a user attempts to call len() on some Iterable, Python will look into that Iterable's
__len function to return the answer. Similarily the
__getitem__(index) is indirectly used through list bracket accessing. When a user attempts to access some element(s) of an Iterable using brackets, Python will use the Iterable's
__getitem__(index) function to determine what to return.
>>>Counter c = Counter(24, 42) >>>c.__len__() 19 >>>len(c) #Use this 19 >>>c.__getitem__(3) 27 >>>c #and this 27
Two other prevalent examples of Iterables in use are the
for loop and the
in keyword. The
for keyword is used for Python's for loops. Users may use a for loop to quickly traverse an Iterable and gain access to each of its elements. Rather than "getting" each element and printing them out one at a time, a simple for loop can reduce the redundancy of repeated statements. The in keyword can be used to check if an element is in an Iterable. The general syntax for an
in statement is shown below.
>>>Counter c = Counter(24, 42) >>>30 in c True >>>500000 in c False
Using either of these keywords on an Iterable requires that the
__getitem__(index) functions are implemented. Python implicitly calls upon those two functions when processing
for loop and the
- Iterator - A protocol that requires a
__next__method, not to be confused with the Iterable protocol.
-  Iterator vs. Iterable answer on StackOverflow