Signup/Sign In

Iterable and Iterator in Python

In python or in any other programming language, Iteration means to access each item of something one after another generally using a loop. For example if we have a list of car names and we want to print all the names one by one, we can do so using a for loop, like this:

# list of cars
cars = ['Audi', 'BMW', 'Jaguar', 'Kia', 'MG', 'Skoda']

for car in cars:
  print("Name of car: ", car)

Name of car: Audi Name of car: BMW Name of car: Jaguar Name of car: Kia Name of car: MG Name of car: Skoda

What we did in the code above was iteration which involved accessing all the items of the list one by one.


What is an Iterable?

In python programming, an iterable is anything that can be looped through or can be iterated over. For example, list, tuples, dictionaries, etc. all are iterables. In simpler words, anything that can appear on the right-side of a for-loop: for x in iterable: ... is an iterable.

One important property of an iterable is that it has an __iter__() method or iter() method which allows any iterable to return an iterator object.

The iter() method internally makes a call to the __iter__() method and returns an iterator object.


What is an Iterator?

Iterator is an object which can be looped through and it maintains its state during the iteration which means it remembers where it is during an iteration.

It has a __next__() method that returns the next value in the iteration and updates the state to point at the next value.

Iterators also have the __iter__() method that returns self object.


Getting an Iterator object from Iterable

We can easily get an iterator object by passing a predefined or pre-created iterable to the iter() method or by using the __iter__() method on that iterable.

For example:

In the example above, we have used the iter() method, well we can try using the __iter__() method too, like this:

# we can use __iter__() method too
cars_iter_new = cars.__iter__()

# print the data
print(cars_iter_new.__next__())

As you can see in the example above, the next() or the __next__() method increments the state of the corresponding iterator and returns the value that is next to the previous value.

Also, you must have noticed an exception in the output. The exceotion is the StopIteration exception which occurs when there are no values left in an iterator to iterate i.e. after the list has ended and we still try to call the next() or __next() method.


Is this how for Loop works internally?

Well yes! Rather than getting into all the trouble of getting the iterator object and then calling next function again and again, python provides us with loops like the for loop which internally performs all above steps.

So when we use a for loop like this:

# list of cars
cars = ['Audi', 'BMW', 'Jaguar', 'Kia', 'MG', 'Skoda']

for car in cars:
  print("Name of car: ", car)

Internally, the for loop does this:

# iterator object is created
iter_obj = iter(cars)

while True:
	try:
		element = next(iter_obj)
		# perform some operation like print the value
	except StopIteration:
	    # break out of loop when the list ends 
		break

for loop in python is created to easily iterate over the iterables and now we know how it works internally using the iterator object.


Making a class Iterable by creating custom Iterator

Now let's learn how to make our own iterators. It is super easy to make our own iterator, all we have to do is implement the methods __iter__() and __next().

The __iter__() method will return an object of the iterator which in our case will be the object of the class itself.

And the __next__() method should return the next element every time it is called and should raise the StopIteration exception upon reaching the end.

Below we have a simple class Counting which will print the counting starting from 1 till the number that you provide while initializing the class.

You can also try to call the iter() method on the object of the Counting class and then use the next() method on the iterator to print the values one by one.