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

Unlock This Lesson

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

Unlock This Lesson

Efficient Iterations With Python Iterators and Iterables (Summary)

You’ve learned a lot about Python iterators and iterables. Now you know what they are and what their main differences are. You learned how to create different types of iterators according to their specific behavior regarding input and output data.

You studied generator iterators and learned how to create them in Python. Additionally, you learned how to build your own iterables using different techniques. Finally, you touched on asynchronous iterators and asynchronous loops in Python.

In this video course, you learned how to:

  • Create your own iterators using the iterator protocol in Python
  • Differentiate iterators from iterables and use them in your code
  • Use generator functions and the yield statement to create generator iterators
  • Build custom iterables using different techniques, such as the iterable protocol
  • Write asynchronous iterators using the asyncio module and the await and async keywords

With all this knowledge, you’re now ready to leverage the power of iterators and iterables in your code. In particular, you’re able to decide when to use an iterator instead of iterable and vice versa.


Course Slides (.pdf)

1.0 MB

Sample Code (.zip)

3.6 KB

00:00 In the previous lesson, I went full circle returning to interables themselves. In this lesson, I summarized the course and point you at other resources that may be of interest.

00:10 The for loop in Python works by iterating over an iterable where an interable is any object that defines __iter__. To iterate over an iterable, you need an iterator, a special object used to track the current position in the iterable and what value gets returned.

00:27 Next in the loop, iterators require two magic methods, __iter__ and __next__, which together are known as the iterator protocol.

00:37 All iterators are iterable since they define __iter__, but the reverse isn’t true. Not all iterables have __next__. For both iterables and iterators, __iter__ returns an iterator, which in the case of an iterable is its associated iterator, and for an iterator, it’s the iterator itself.

01:00 The other part of the protocol is __next__, which is the method called to get the subsequent item in the iteration. If the iteration is complete, __next__ raises StopIteration instead of returning a value.

01:15 A generator function is a shortcut for creating iterators. A function becomes a generator by using the yield keyword inside of it. The value you associate with the yield keyword is the subsequent item in an iteration, what you’d otherwise return from __next__ in an iterator.

01:32 Unlike regular functions which run to completion, generator functions return without doing anything, responding with a generator iterator. This iterator is then used like any other iterator.

01:44 Python takes care of the __iter__, and __next__ process by calling the function and using the yielded values.

01:51 In addition to yield on its own, you can also use yield from. This is a shortcut for creating generators, which themselves are shortcuts to iterators.

02:01 When you yield from an iterable, a generator gets created that iterates over that iterable. Another shortcut for creating generators is a generator expression.

02:11 These use syntax almost identical to list comprehensions, but with parentheses instead of square brackets.

02:19 Python has two built-in functions for dealing with iterators: iter() and next(). These invoke a class’s underlying __iter__ and __next__.

02:27 A for loop starts out by calling iter on the value given within the in part of the for statement. This creates an iterator, which for then calls next on in order to get the subsequent value.

02:41 Instead of writing a whole iterator class for your iterable, you can quickly embed one in the __iter__() method using the built-in iter function, yield or yield from to create inline generators.

02:55 A sequence is a container with directly accessible items like a list or the characters in a string. Sequences are also sliceable. To be a sequence, an object implements the sequence protocol, which consists of __len__ to return the length of the sequence and __getitem__ to return the value at a given index.

03:16 __len__ gets called by the built-in len function, whereas __getitem__ gets called when you use square brackets on an object.

03:23 Objects that implement the sequence protocol are automatically iterable. Python takes care of this for you, even if you don’t implement __iter__.

03:33 Here are some resources in case you wish to drill down more on some of the topics covered in this course.

03:39 This tutorial covers how single and double underscore names get used in Python. While this one is specific to __dunder__ methods covering a whole lot of them, there are over a hundred __dunder__ methods that a Python class can use, so there’s lots more to learn in dunderland.

03:55 Although I covered generators quickly, this tutorial and associated course might be of interest to you if you’d like to learn more. And finally, I briefly hinted at the existence of concurrent programming in Python.

04:06 This tutorial and corresponding course teach you all about the async and await keywords along with the asyncio library.

04:13 Put your thinking caps on for this one. Parallel programming can get messy. That’s all from me. I hope this course gave you a deeper understanding of iteration in Python.

04:23 Thanks for your attention.

Become a Member to join the conversation.