Thursday Mornings With Python, Part 4
Thursday Mornings With Python, Part 4
Continuing with iterators - Next
Awwww how cute - the next lesson also just happens to be on something called next. There is a method in iterators called next() and it can be used as next() or __next__(), and it works similarly to iter() and __iter__(). The moment I saw the title of the less I got it straight away. I don't want to spend too long on it. But what does it do under the hood? Basically, next in whatever form you choose, RETRIEVES THE ITERATOR'S NEXT VALUE.
It will raise an exception called StopIteration when all items have ben iterated through. But then what happens - does the exception get handled? PYTHON HANDLES THE EXCEPTION StopIteration BY STOPPING THE LOOP WITHOUT THROWING AN ERROR (during a for loop).
Iterators and For Loops
This literally just explains what is going on under the hood with for loops - then we can create our own custom iterators.
- iter()
- next()
- and StopIteration
Custom Iterators
- the methods __iter__() and __next__() must be implemented for an object to be an iterator object
- The implementation of these methods is called iterator protocol
- "If we desire to create our own custom iterator class, we must implement iterator protocol". Which means that "we need to have a class that defines at miniumum the __iter__() and __next__() methods."
- And maybe more?
Custom classes are not iterable.
But we might have a class that needs the ability to iterate?! In that case we can define the __iter__() and __next__() methods for ourselves.
class DreamsInventory:
def __init__(self, dreamList):
self.all_dreams = dreamList
If we want to add to it we must define it more by implementing the iterator protocol by defining the __iter__() and __next__() methods.
We want to make the DreamInventory class iterable. Adding a class member within the __iter__() method called index will help us to keep track of the current position in the list that we're at. Very important: the __iter__() method returns itself since this class WILL BE AN ITERATOR OBJECT. Huh? I don't get this.
Okay I think I do now - we can use iter() to turn another object into an iterable - but it is usually just called on itself. Is this right please? Thanks.
I'm gonna ask Chat GPT...
Chat GPT says:
__iter__()
method, you're saying, "Give me an iterator to loop through."self
, you're saying, "This object is the iterator."Okay yes there I think I get it. We're saying - this specific instance of this class is the specific object that we want to loop over. It is saying - I am both the looped over object and the object that will do the looping.
Remember we need to raise a StopIteration exception otherwise our code will error . That means we need to use an if/else statement (classic) to check for this condition.
class DreamsInventory:
def __init__(self, dreamList):
self.all_dreams = dreamList
def __iter__(self):
self.index = 0
return self
def __next__(self):
if self.index < len(self.all_dreams):
dream = "One of your dreams is to " + self.all_dreams[self.index]
self.index += 1
return dream
else:
raise StopIteration
Python's Itertools: Built-in Iterators
🤔🤔
Python's module named "itertools" provides the ability to create complex iterator manipulations.
There are three categories of itertools iterators:
- Infinite iterators
- These will repeat an infinite number of times
- They will not raise a StopIteration exception and will require some form of stop condition to exit from
- Input-Dependent Iterators
- They are terminated by the input iterable(s) sequence length.
- This is all so vague to me thanks and I need to see it to get it more so let's see thanks.
- The smallest length iterable parameter of an input-dependent iterator will terminate the iterator.
- HUH?
- Combinatoric Iterators
- these are iterators that are COMBINATIONAL
- mathematical functions are performed on input iterable(s).
What none of this makes any sense.
Show me the code already haha. Also, you need to import these.
Infinite Iterator: Count
I mean, this feels a bit like a JavaScript while loop... which no-one ever uses and everybody dislikes or hates.
Questions
- When we do def __iter__(self):self.count = 0return self
then why do we return self? It made sense to me at first but then of course the Codecademy course confused me - anyway, thanks.
- Chat GPT said something to me that was interesting like "I am both the object that is iterated over and the one that does the iterating" and I would like to understand this a bit better please. Thanks.
- Why can't instances of Python classes just be iterable by default? Isn't that a bit dumb please? Thanks.
- Could we maybe talk a bit more about the three types of iterators please? Thanks. Or do I not need to know them? Do I not need to care please? Thanks.
- This is super interesting and can't wait to learn more - could see myself spending an hour or two on it over the weekend over it just because I'm dying to know.
- Is an infinite iterator like a JavaScript while loop?
Post Q+A Session
I had a really lovely session as always.
I get to ask questions and share what I have learned in the morning and really learn loads.
It is so so so amazing.
I was given a link to the Python documentation to read: https://docs.python.org/3/glossary.html#term-iterator
OMG THIS IS SO SO BEAUTIFUL WOW. THIS IS SO SO SO SO BEAUTIFUL WOW
"An object representing a stream of data." That is what an iterator is.
"Iterators are required to have an __iter__() method that returns the iterator object itself so every iterator is also iterable and may be used in most places where other iterators are accepted." Wait what???! What does this mean please - thanks.
As always I will ask Chat GPT...
I'm afraid I still don't get it so I have asked my senior colleague, and if needs be I will ask around wider in the company.
I think we finally made it click with the
def __iter__(self):
self.count = 0
return self
thing.
It's just basically like a variable reassignment thing. Wow.
Comments
Post a Comment