Iterators in Python
In Python, an iterator is an object used to iterate across iterable objects such as lists, tuples, dicts, and sets. The iter() function is used to initialize the iterator object. It iterates using the next() function. The __iter(iterable)__ function is used to initialize an iterator. This function returns an iterator object. following (__next__ in Python 3) The iterable’s next value is returned via the next method. When we use a for loop to traverse any iterable object, it internally utilizes the iter() function to get an iterator object, which we then iterate over using the next() method. To signify the end of the iteration, this method raises a StopIteration.
The actual workings of a Python iterator:-
Example:
value_iter = 'Python'
bool_value = True
object_iter = iter(value_iter)
while bool_value:
try:
iterable_item = next(object_iter)
print(iterable_item)
except StopIteration:
break
Output:
P
y
t
h
o
n
The Python custom iterator below defines an iterator type that iterates from 100 to a defined limit. If the limit is 110, it will display 100 101 102 103 104 105 106 107 108 109 110. And if the limit is less than 100, nothing is printed; 90 prints nothing.
Example:
class CustomIteration:
# Constructor
def __init__(self, limit):
self.limit = limit
def __iter__(self):
self.lower_limit = 100
return self
def __next__(self):
next_value = self.lower_limit
if next_value > self.limit:
raise StopIteration
self.lower_limit = next_value + 1
return next_value
for i in CustomIteration(110):
print(i)
for i in CustomIteration(90):
print(i)
Output:
100
101
102
103
104
105
106
107
108
109
110
The for loop is internally (although we can’t see it) utilizing an iterator object to traverse the iterables in the subsequent iterations.
Example:
print("List Iteration")
print("------------------------------")
l = ["enablegeek", "is", "awesome"]
for i in l:
print(i)
print("\nTuple Iteration")
print("------------------------------")
t = ("enablegeek", "is", "awesome")
for i in t:
print(i)
print("\nDictionary Iteration")
print("------------------------------")
d = dict()
d['number'] = 381
d['value'] = 1055
for i in d :
print("%s %d" %(i, d[i]))
print("\nString Iteration")
print("------------------------------")
s = "Python"
for i in s :
print(i)
Output:
List Iteration
------------------------------
enablegeek
is
awesome
Tuple Iteration
------------------------------
enablegeek
is
awesome
Dictionary Iteration
------------------------------
number 381
value 1055
String Iteration
------------------------------
P
y
t
h
o
n
Iterator Functions
Iterator functions for effective looping and accelerating code execution are also permitted under Python’s definition. The module “itertools” has a plethora of built-in iterators. Several iterator-building components are put into practice in this section.
Iterators that are useful:
- chain(iter1, iter2..): This method prints all the values in iterable targets in the order specified in its parameters.
- accumulate(iter, func): This iterator accepts two arguments: an iterable target and the function to be followed at each iteration of the value in target. If no function is specified, addition is performed by default. If the input iterable is empty, so will the output iterable.
- chain.from iterable(): This function is identical to chain() in implementation, but the parameter is a list of lists or any other iterable container.
- compress(iter, selector): This iterator chooses values to output from the supplied container based on the boolean list value passed as the other argument. If true, the arguments are written; otherwise, they are skipped.
- dropwhile(func, seq): This iterator begins printing characters only after the first time the func. in parameter returns false.
- filterfalse(func, seq): As the name implies, this iterator outputs only values for the provided function that return false.
Example:
import itertools
import operator
list_one = [1, 2, 3, 4]
list_two = [5, 6, 7, 8]
list_three = [9, 10, 11, 12]
succesive_sum = list(itertools.accumulate(list_one))
print("Successive addition : ", succesive_sum)
print("---------------------------")
succesive_multiplication = list(itertools.accumulate(list_one, operator.mul))
print("Successive product: ", succesive_multiplication)
print("---------------------------")
chained_list = list(itertools.chain(list_one, list_two, list_three))
print("Chained List : ", chained_list)
print("---------------------------")
list_four = [list_one, list_two, list_three]
values_chained = list(itertools.chain.from_iterable(list_four))
print("Values of chaned list : ", values_chained)
print("---------------------------")
us = 'ENABLEGEEK'
our_vowels = [1, 0, 1, 0, 0, 1, 0, 1, 1, 0]
our_consonant = [0, 1, 0, 1, 1, 0, 1, 0, 0, 1]
vowels = list(itertools.compress(us, our_vowels))
consonant = list(itertools.compress(us, our_consonant))
print("Compressed values are(vowels) : ",vowels)
print("---------------------------")
print("Compressed values are(consonant) : ",consonant)
print("---------------------------")
list_five = [12, 14, 126, 2, 4, 5, 7, 8]
dropwhile_value = list(itertools.dropwhile(lambda x : x%2==0,list_five))
print ("The values after condition returns false : ",dropwhile_value)
print("---------------------------")
filterfalse_value = list(itertools.filterfalse(lambda x : x%2==0,list_five))
print ("The values that return false to function are : ",filterfalse_value)
print("---------------------------")
Output:
Succesive addition : [1, 3, 6, 10]
---------------------------
Successive product: [1, 2, 6, 24]
---------------------------
Chained List : [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
---------------------------
Values of chaned list : [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
---------------------------
Compressed values are(vowels) : ['E', 'A', 'E', 'E', 'E']
---------------------------
Compressed values are(consonant) : ['N', 'B', 'L', 'G', 'K']
---------------------------
The values after condition returns false : [5, 7, 8]
---------------------------
The values that return false to function are : [5, 7]
Iterators are an essential feature of Python programming as they allow for the efficient processing of large amounts of data. The main advantage of using iterators is that they enable us to access a large amount of data without loading it all into memory at once. This makes it possible to process large data sets and streams of data that are too big to fit into memory.
Iterators are also important because they allow for lazy evaluation of data. This means that data is only evaluated when it is needed, which can lead to significant performance improvements in many cases. Iterators are used in many built-in Python functions, such as range(), map(), and filter().
Furthermore, iterators enable us to create our own custom data types in Python that can be used in a variety of ways. By implementing the Iterator Protocol, we can create iterable objects that can be used in for loops, comprehensions, and other Python constructs that require iterable objects.