Locked learning resources

Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Locked learning resources

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Creating Custom Iterators

00:00 Based on what you learned in the last lesson, you need two magic methods to create your own custom iterators. Calling the __iter__ magic method initializes the iterator and must return and iterator object, usually the iterator itself and calling the __next__ magic method iterates over the iterator and must return the next value in the data stream.

00:26 This convention is called the Iterator Protocol.

00:30 Let’s get practical and create a class that provides an iterator over the numbers in the Fibonacci sequence. Just as a reminder, the Fibonacci sequence is a series of numbers where each number is the sum of the two proceeding ones starting from zero and one. So it goes like 0 1, then zero plus one is one, so it becomes 0 1 1.

00:53 The next number in the sequence is one plus one, which is 2, and so on.

01:01 Let’s start by defining the FibonacciIterator class.

01:06 Now you have to set up the __init__ magic method here you need to set up the initial two Fibonacci numbers, zero and one, and also keep track of how many numbers have been generated so far.

01:18 You’ll include a max_count parameter to limit the number of iterations. So you need a self.current and also a self.next.

01:29 Now there are just zero and one, and you also need to set up your max_count self .max_count equal to the max_count that you’ll get when you instantiate the FibonacciIterator class.

01:46 You also need a self.count. This keeps track of how many Fibonacci numbers have been produced so far. It has to do with the StopIteration exception error message you learned about in the last lesson and starts from zero.

02:05 That’s the __init__ magic method initialization. Now, you need to make your class an iterator. You need to follow the iterator protocol, so you need an __iter__ magic method.

02:18 So def __iter__(self): The __iter__ method returns the iterator object itself, which is necessary for making the class an iterable.

02:32 The next magic method you need to implement is the __next__ magic method. You’ll define how the Fibonacci numbers will be generated here one by one while also respecting the max_ count limit that you set earlier.

02:48 So def __next__(self): Here if max_count is set and the number of generated Fibonacci numbers has reached this limit, the iterator should raise the StopIteration exception signaling that, hey, there are no more items for me to produce.

03:11 So if self.max_count is not None, and also self.count is bigger or equal to self.max_count, you need to raise StopIteration. Now, before you actually replace the current Fibonacci number with the next one, you need to store it in a variable.

03:38 Let’s name it value = self.current.

03:43 And now you can advance the sequence by updating self.current and self.next will be equal to so the current one would be advancing to the next one.

03:54 So self.next and self.next will become self.current plus self.next.

04:04 And don’t forget that you have to add one to the current count number. So self.count, whatever it is now, it should be plus one. Okay, perfect. Now you can actually return value variable here, which is the next number in the sequence.

04:24 Okay, perfect. You did a lot here so let’s recap. In the __next__ magic method the current Fibonacci number is stored in value and then the sequence is advanced by updating self.current and self.next. The self.count variable keeps track of how many numbers have been generated so far, and finally, you’re returning value, which gives you the next number in the sequence, and that’s it.

04:51 You just created a custom iterator by following the Iterator protocol, meaning you implemented the __iter__ and __next__ magic methods here.

05:02 Now you can use this class to create an iterator that generates a specific number of a Fibonacci numbers and you can use the next() built-in function to retrieve them.

05:14 Let’s go ahead and do exactly that. So let’s create an iterator that provides the first ten Fibonacci numbers. First, you need to create an instance, let’s call it fib_iterator equal to the FibonacciIterator, and the max_count should be equal to 10.

05:38 Now here you can call next() on fib_iterator multiple times by hand, or you can just use a for loop to do that. So we’re gonna be doing the for loop option.

05:49 Let’s say for i in range(10): print( next(fib_iterator))`.

06:02 Okay, let’s see if this works.

06:08 And it does. We have 0 1, 1, 2, 3, 5, 8, 13, 21, and 34, which is the correct sequence. So it works. Now to make sure that everything works, let’s also check the StopIteration exception that you created earlier.

06:28 So after the for loop, let’s again use the next() function on fib_iterator. So let’s do that. print(next(fib_iterator))

06:41 Let’s see what happens now. And indeed, you get the sequence until 34, and then you get a StopIteration exception. It works.

Become a Member to join the conversation.