Yield analysis in Python

  • 2020-04-02 13:46:19
  • OfStack

It is necessary to explain the iterators and constructors in Python before introducing yield.

I. iterator

In Python, a for loop can be used for any type in Python, including lists, primitives, and so on. In fact, a for loop can be used for any "iterable object," which is essentially an iterator

An iterator is an object that implements the iterator protocol, which in Python is an object with a next method that moves to the next result, and at the end of a series of results that is, raises a StopIteration. Any of these objects can be iterated in Python with a for loop or some other iteration tool, which internally calls the next method on each iteration and captures a StopIteration exception to determine when to leave.

One obvious benefit of using iterators is that reading only one piece of data from an object at a time does not cause excessive memory overhead.

For example, to read the contents of a file line by line, we can use the readlines() method to write:


for line in open("test.txt").readlines():
    print line

It works, but it's not the best way. Because he actually loads the file once into memory and then prints it out line by line. When the file is large, the memory overhead of this method is large.

Using the iterator of file, we can write:


for line in open("test.txt"):   #use file iterators
    print line

This is the easiest and fastest way to write it. It does not explicitly read the file, but USES an iterator to read the next line at a time.


2. Constructor

The generator function is associated in Python with the concept of the iterator protocol. In short, the function containing the yield statement is specifically compiled as a generator. When functions are called, they return a generator object that supports the iterator interface. The function might have a return statement, but its purpose is to yield a value.

Unlike normal functions that generate values and exit, generator functions automatically suspend and suspend their execution and state after they generate values, and their local variables hold state information that is again valid when the function resumes


>>> def g(n):
...     for i in range(n):
...             yield i **2
...
>>> for i in g(5):
...     print i,":",
...
0 : 1 : 4 : 9 : 16 :

To understand how it works, let's use the next method:

>>> t = g(5)
>>> t.next()
0
>>> t.next()
1
>>> t.next()
4
>>> t.next()
9
>>> t.next()
16
>>> t.next()
Traceback (most recent call last):
  File "", line 1, in 
StopIteration

After running next five times, the generator throws a StopIteration exception that terminates the iteration.
Let's take another yield example and use the generator to generate a Fibonacci sequence:


def fab(max):
    a,b = 0,1
    while a < max:
        yield a
        a, b = b, a+b
>>> for i in fab(20):
...     print i,",",
...
0 , 1 , 1 , 2 , 3 , 5 , 8 , 13 ,

See here should be able to understand the very abstract concept of generator ~~


Related articles: