Iterator: Python String Python List Python Dictionary

Download as doc, pdf, or txt
Download as doc, pdf, or txt
You are on page 1of 8

Iterator

Iterator is an object which allows a programmer to traverse through all the


elements of a collection.

Basically an iterator is an object which is used to iterate through an iterable


element.

Python Iterator and Iterable Elements


Most of the objects of Python are iterable. In python, all the sequences
like Python String, Python List, Python Dictionary etc are iterable.
Now, what is iterator?
Suppose, we have a group of 5 boys standing in a line. You are pointing at the
first boy and ask him about his name. Then, he replied. After that, you ask the
next boy and so on.
In this case, you are the Iterator and the group of boys is the iterable.

In Python, an iterator is an object which implements the iterator protocol. The


iterator protocol consists of two methods. The __iter__() method, which must
return the iterator object, and the next() method, which returns the next
element from a sequence.

Python has several built-in objects, which implement the iterator protocol. For
example lists, tuples, strings, dictionaries.

How does iteration works in Python?

Iteration works in Python through a concept known as “Iterator Protocol”


Iterables support something called the Iterator Protocol
What is an Iterator Protocol?
In simple it can be thought of as a set of requirements to be satisfied so that we
can use it in a for…in loop on that.
This means that the lists, strings, tuples, sets and dictionaries all follow the
Iterator Protocol, therefore we can use them in for..in loop. 
In opposite objects that do not follow the iterator protocol cannot be used in
a for..in loop. One example of an object that does not follow the iterator
protocol is an integer. If we try to give an integer to a for loop, Python will
throw an error.
num = 12345
for n in num:
print(n)

TypeError: 'int' object is not iterable

An integer is just a singular number, not a sequence.

You may argue that the “first” number in number is 1, but it is not the same as
the first item in a sequence.

It doesn’t make sense to ask “What is the number after 1?” from number since
Python only understands integers as a single entity.

Therefore, one of the requirements to be an iterable is to be able to describe to


the for loop is what is the next item to perform the operation on.

For example, lists tell the for loop that the next item to iterate on it is the
index+1 from the current one. Also an iterable must also signal to a for loop
when to stop iterating. This signal usually comes when we arrive at the end of
a sequence (i.e. the end of a list or string). 
An iterator protocol specifies the following two steps:

1. For a custom class to support iteration, it must implement the __iter__()


method. This method indicates the type is an iterable and also returns
the iterator object.
2. The iterator object will then able to go over the items one by one by
calling its __next__() method until it runs out of items .
The __next__() method also signals it is time to stop by raising
“StopIteration” exception

Iterators have several advantages:

 Cleaner code
 Iterators can work with infinite sequences

 Iterators save resources

Iterators help to produce cleaner looking code because they allows us to work
with infinite sequences without having to reallocate resources for every possible
sequence, thus also saving resource space. Python has several built-in objects,
which implement the iterator protocol and you must have seen some of these
before: lists, tuples, strings, dictionaries and even files
An iterable is any object, not necessarily a data structure that can return an
iterator". Its main purpose is to return all of its elements. Iterables can
represent finite as well as infinite source of data. An iterable will directly or
indirectly define two methods: the __iter__() method, which must return the
iterator object and the __next()__ method with the help of the iterator it calls.

myset = {1, 2, 3}
myiterator = iter(myset)
next(myiterator)

print(type(myset))
print(type(myiterator))
----------------------------------------------------------------------

colourlist =
["Purple","Blue","Pink","Red","Orange","Yellow","Green","White","Black
"]

itercol = iter(colourlist)

#print(itercol)

colour = next(itercol)
print(colour)
colour = next(itercol)
print(colour)
colour = next(itercol)
print(colour)
colour = next(itercol)
print(colour)
colour = next(itercol)
print(colour)
colour = next(itercol)
print(colour)
colour = next(itercol)
print(colour)
colour = next(itercol)
print(colour)
colour = next(itercol)
print(colour)
colour = next(itercol)
print(colour)

colour = next(itercol)
print(colour)

---------------------------------------------------------------------
Let us create a class by name EmailContacts containing the email contacts of
all your customers.

To add iteration support to this class you have to follow the iterator protocol.
To do this, you have to both make the EmailContacts an iterable and make it
return an iterator object. The __iter__ method’s implementation achieves both
of these things.

The iterator object is then used to call the __next__ method to retrieve items


one by one. This method also raises an exception when it runs out of items.

class EmailContacts:
def __init__(self, emails):
self.emails = emails
self.index = 0

def __iter__(self):
return self

def __next__(self):
try:
email = self.emails[self.index]
except IndexError:
raise StopIteration()

self.index += 1
return email

emails = EmailContacts(['[email protected]', '[email protected]',


'[email protected]'])
for email in emails:
print(email)

In the following code we get the iterator object and iterate over it without a
looping construct. The iter(type) method calls the underlying __iter__ method.
In our case the __iter__ is implemented, which makes the EmailContacts an
iterable and also gets us an iterator object.

iterator = iter(EmailContacts(['[email protected]', '[email protected]',


'[email protected]']))
We then use the returned iterator object to call the __next__ method to iterate
over items one at a time until we run out of them.

print(iterator.__next__())
print(iterator.__next__())
print(iterator.__next__())
print(iterator.__next__())

So essentially these are all things that happen behind the scenes when you
iterate over an iterable using a for loop (or in any other iteration context).

----------------------------------------------------------------------

class fibo:
def __init__(self):
# default constructor
self.prev = 0
self.cur = 1
self.n = 1

def __iter__(self): # define the iter() function


return self

def __next__(self): # define the next() function


if self.n < 10: # Limit to 10
# calculate fibonacci
result = self.prev + self.cur
self.prev = self.cur
self.cur = result
self.n += 1
return result
else:
raise StopIteration # raise exception

# init the iterator


iterator = iter(fibo())
# Try to print infinite time until it gets an exception
while True:
# print the value of next fibonacci up to 10th fibonacci
try:
print(next(iterator))
except StopIteration:
print('First 9 fibonacci numbers have been printed already.')
break # break the loop

You might also like