Iterable

From CS 61A Wiki
Jump to: navigation, search

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 __iter__ or __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[1]. 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 self. The __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

Implementation

As stated in the previous section, implementing an Iterable requires the definition of either __iter__(), or__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

In this Counter example[2], we define __len__ and __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.

Use

How are Iterables and their functions used?

The __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[3]   #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 __len and __getitem__(index) functions are implemented. Python implicitly calls upon those two functions when processing for loop and the in.

See also

  • Iterator - A protocol that requires a __next__ method, not to be confused with the Iterable protocol.

References

  1. [1] Iterator vs. Iterable answer on StackOverflow
  2. http://stackoverflow.com/questions/19151/build-a-basic-python-iterator