Iterator in Python
In Python, an iterator is an object that can be iterated (looped) upon. An object which will return data, one element at a time. They are used to represent a stream of data. In Python, an iterator object implements two methods, __iter__()
and __next__()
.
The __iter__()
method returns the iterator object itself. The __next__()
method returns the next value from the iterator. If there are no more items to return, it should raise StopIteration.
Here is an example of how to create an iterator:
class MyIterator: def __init__(self, start, end): self.start = start self.end = end def __iter__(self): return self def __next__(self): if self.start < self.end: num = self.start self.start += 1 return num raise StopIteration for i in MyIterator(1, 5): print(i)
Output:
1 2 3 4
In Python, we also have a built-in function called iter() which can be used to create an iterator.
my_list = [1, 2, 3, 4, 5] my_iter = iter(my_list) print(next(my_iter)) print(next(my_iter)) print(next(my_iter))
Output:
1 2 3
Python also provides several built-in objects that implement the iterator protocol, including lists, tuples, and strings. In addition, we can use the for
loop to iterate over any iterable.
my_list = [1, 2, 3, 4, 5] for i in my_list: print(i)
Output:
1 2 3 4 5
In python, the most commonly used iterator is the for
loop.
Some other examples of iterators are:
enumerate(iterable, start=0)
zip(iter1, iter2, ...)
map(function, iterable)
filter(function, iterable)
You can find more information about Iterator in python in the official documentation: https://docs.python.org/3/library/stdtypes.html#iterator-types
In addition to the built-in iterators, you can also create your own iterators by defining a class that implements the iterator protocol. The iterator protocol consists of two methods: _
_iter__()
and __next__()
. The __iter__()
method returns the iterator object itself, and the __next__()
method returns the next value from the iterator. If there are no more items to return, it should raise StopIteration.
Here is an example of how to create an iterator that generates the Fibonacci sequence:
class Fibonacci: def __init__(self, max): self.max = max def __iter__(self): self.a = 0 self.b = 1 return self def __next__(self): fib = self.a if fib > self.max: raise StopIteration self.a, self.b = self.b, self.a + self.b return fib for n in Fibonacci(1000): print(n)
Output:
0 1 1 2 3 5 8 13 21 34
In Python, you can also use the yield
statement to create an iterator. The yield
statement is used in a function like a return statement, but when the function is called, it returns a generator object instead of a single value. Each time the generator’s __next__()
method is called, the function resumes execution from where it left off, and the value of the yield
expression is returned.
Here’s an example of using the yield
statement to create a generator that generates the Fibonacci sequence:
def fibonacci(max): a, b = 0, 1 while a < max: yield a a, b = b, a + b for n in fibonacci(1000): print(n)
Output:
0 1 1 2 3 5 8 13 21 34
With the above examples, you have learned the basics of using iterators in Python. It’s a powerful tool that allows you to work with large data sets and perform complex operations in a more efficient and readable way.
Another useful tool related to iterators in Python is the iter()
function. The iter()
function returns an iterator object for a given iterable. For example, you can use it to create an iterator for a list, tuple, or string:
my_list = [1, 2, 3, 4, 5] my_iter = iter(my_list) print(next(my_iter)) # 1 print(next(my_iter)) # 2
You can also pass a second argument to iter()
function, which is the sentinel value. The iterator will raise a StopIteration
exception when the next item to be returned is equal to the sentinel.
my_iter = iter(my_list, 3) print(next(my_iter)) # 1 print(next(my_iter)) # 2 print(next(my_iter)) # StopIteration
Another powerful built-in tool related to iterators is the itertools
module, which provides a variety of functions that can be used to work with iterators. Some of the most useful functions in this module include:
itertools.chain()
: Takes multiple iterables as arguments and returns an iterator that yields elements from the first iterable, then the second, and so on.itertools.compress()
: Takes an iterable and a corresponding iterable of Boolean values, and returns an iterator that yields elements from the first iterable for which the corresponding Boolean value isTrue
.itertools.groupby()
: Takes an iterable and a key function, and returns an iterator that yields pairs of the form (key, group), where key is the result of the key function applied to the first element of the group, and group is an iterator that yields all of the elements in the group.itertools.islice()
: Takes an iterable and two indices, and returns an iterator that yields elements from the input iterable starting at the first index and ending before the second index.itertools.tee()
: Takes an iterable as an argument and returns multiple independent iterators (or “tees”) that can be used to iterate over the data in the input iterable.
Here is an example of how to use itertools.chain() to concatenate multiple lists into one iterator:
import itertools list1 = [1, 2, 3] list2 = [4, 5, 6] list3 = [7, 8, 9] final_list = itertools.chain(list1, list2, list3) for i in final_list: print(i)
Output:
1 2 3 4 5 6 7 8 9
In conclusion, iterators are an essential part of the Python language and provide a powerful and efficient way to work with large data sets and perform complex operations. The built-in iter()
function, for
loop, and itertools
module, along with the ability to create your own iterators, make it easy to use and take full advantage of the iterator protocol.
Iterable Vs Iterator
In Python, an iterable is an object that can be used in a for loop or with other functions that work with iterators. It has an __iter__()
method that returns an iterator object, which is used to iterate over the elements of the iterable. Examples of built-in iterables in Python include lists, tuples, and strings.
An iterator, on the other hand, is an object that represents a stream of data, and it has two methods: _
_iter__()
and __next__()
. The __iter__()
method returns the iterator object itself, and the __next__()
method returns the next value from the iterator. If there are no more items to return, it should raise StopIteration.
In a nutshell, an iterable is an object that can be looped over, while an iterator is an object that is used to loop over an iterable.
For example, a list is an iterable, and when you use a for loop to iterate over it, the for loop calls the list’s __iter__()
method to get an iterator. The iterator object has a __next__()
method that is called by the for loop to get the next item from the list.
my_list = [1, 2, 3, 4, 5] # my_list is an iterable for i in my_list: print(i) # This is equivalent to: my_iter = iter(my_list) # my_iter is an iterator print(next(my_iter)) print(next(my_iter)
In summary, an Iterable is an object that can be used with a for loop, and an Iterator is an object that is used to iterate over an iterable. The iterator is an object that implements the iterator protocol which consist of _
_iter__()
and __next__()
methods.