This is the fifth day of my participation in the August More text Challenge. For details, see: August More Text Challenge

In Python, iterators, generators, no doubt is one of the most useful features, function also is very strong, often occurs in Python, but often ignored by us, or don’t understand the principle of their mechanism, this paper revolves around an iterator, generator, object iteration to elaborate the relationship between them and their strong place.

Iterable object

When it comes to iterators and generators, iterable objects must be the point that can’t be circled. Then what is iterable? The simplest explanation is: objects that can use for··· ···in··· statement to loop are iterable objects, such as strings, lists, tuples, dictionaries and so on that we are familiar with belong to iterable objects.

So how do you tell if an object is an iterable? We can use isinstance() to judge.

from collections.abc import可迭代print(isinstance([], Iterable))
print(isinstance([1.2.3.4], Iterable))
print(isinstance({"name": "tigeriaf"}, Iterable))
print(isinstance("tigeriaf", Iterable))
print(isinstance((1.2.3.4), Iterable))
Copy the code

Because they are both iterable, the result is True.

It is also important to note that an iterable needs to implement the __iter__ method. That is, an object that implements the __iter__() method is an iterable. For example, the following MyIter class implements the __iter__() method, so its object A is an iterable.

class MyIter:
    def __init__(self) :
        pass

    def __iter__(self) :
        yield self  # __iter__() needs to return an iterator


a = MyIter()


print(isinstance(a, Iterable))
for i in a:
    print(i)
Copy the code

The result is:

True
<__main__.MyIter object at 0x01A9FEB0>

Process finished with exit code 0
Copy the code

The Iterator Iterator

Iterators are a subset of iterables that remember where to iterate. They are distinguished from lists, tuples, collections, and strings by the next() method. Iterators use the next() method to retrieve the next value until all the elements have been printed. To stop, return the StopIteration exception. That is, iterators need to implement __iter__() as well as __next__().

For example, the following code defines a custom iterator by implementing __iter__() and __next__() methods.

class MyRange:
    def __init__(self, stop, start=0) :
        self.start = start
        self.stop = stop

    def __iter__(self) :
        # Since __next__() is an iterator, we can return ourselves directly
        return self

    def __next__(self) :
        if self.start < self.stop:
            res = self.start
            self.start += 1
        else:
            raise StopIteration
        return res


print(isinstance(MyRange(3), Iterable))
print(isinstance(MyRange(3), Iterator))

for i in MyRange(3) :print(i)
Copy the code

The result is:

True
True
0
1
2

Process finished with exit code 0
Copy the code

Iterables such as lists, tuples, collections, and strings can also be converted to iterators using the iter() function. Here’s an example.

a = [1.2.3.4.5]
print(isinstance(a, Iterator))
b = iter(a)
print(isinstance(b, Iterator))
print(next(b))
print(next(b))
Copy the code

The output is:

False
True
1
2

Process finished with exit code 0
Copy the code

As you can see from the result, the iter function converts a into an iterator that can be iterated back and forth through the next() method.

The Generator Generator

We said that iterators are a subset of iterables, and generators are a subset of iterators. Generators are implemented using the keyword yiled. In Python, a function can replace its return value with yiled, which makes it a generator object. It is different from an iterator in that the generator does not load all the values into memory at first, but only returns a value when it needs to be fetched using the next() function, so that it does not take up a lot of memory in very large quantities.

def func(end) :
    start = 0
    while start < end:
        yield start
        start += 1

print(isinstance(func(4), Generator))
Copy the code

The result is True.

Generator expression

Generator expressions are a convenient way to implement a generator by replacing brackets with parentheses in a list derivation. Difference from a list derivation: A list generator starts by creating a list directly, but a generator expression is a form of loop and calculation, allowing the list elements to be extrapolated one by one during the loop without the need to create a complete list, thus saving a lot of space.

g = (x * x for x in range(100))
Copy the code

conclusion

  • To achieve the__iter__()The object of the method is Iterable. Common Iterable objects include lists, tuples, collections, strings, etc.
  • To achieve the__iter__()and__next__()Method is an Iterator;
  • The object to which the yield keyword is applied in a function is a Generator, which is also an iterator and an iterable.
  • Both the Iterator and the Generator need to get their internal values one by one, either through a for loop or by manually calling next().
  • The use of iterators and generators can save memory, but only if we can follow some algorithm to calculate the desired elements in the process of the loop.

Put a picture of the big guy, link:

Finally, I would like to thank my girlfriend for her tolerance, understanding and support in work and life.