Sunday, 10 April 2022

Your Iterator is also an Iterable

I already explained in this previous post that generators in JavaScript and Python work in a very similar way (a generator function creates a generator object, that is both an iterable and a iterator).

Most times, for Iterable objects that have not been created with a generator fuction (hence, are not generator objects), the Iterator that we obtain from them is a different object, and we can create different iterators over the same iterable and iterate independently. What is pretty interesting is that Python's iteration protocol dictates that iterators have to be iterables also. That means that calling iter() passing on an iterator will return that iterator. From here:

The strangest fact about iterators is that they are also iterables.
When you pass an iterator to the iter function it'll return itself back

JavaScript iteration protocol is less demanding, as it does not require iterators to be iterable. However, I've recently learned here that all ES6 built-in iterators follow the python approach, so they are iterables with a [Symbol.iterator] method that returns the iterator:


[Symbol.iterator]() {
    return this;
}

An example:


> let ar = ["a", "b"];
undefined
> let iterator = ar[Symbol.iterator]();
undefined
> let iterator2 = iterator[Symbol.iterator]();
undefined
> iterator === iterator2;
true

Another interesting thing that I've recently learnt, this time in Python, is that the file object (I tend to call it file-handle) obtained when opening a a file in read mode is both and iterable and an iterator (so it's as if it had been created by a generator function)


>>> fh = open("commands.txt", "r")
>>> fh is iter(fh)
True

No comments:

Post a Comment