python generator yield functions and expressions

1 python generator yield function and expression

Python generators include generator functions and generator expressions.

NO Generator Description
1 Generator function A function whose main body contains a yield statement and returns a generator object. Each time __next__() is called, a result is returned when the yield statement is executed and execution stops. The following statements are called again and the statements following the return result continue to execute until the yield statement returns the result.
2 Generator expression List parsing written in parentheses, returning the generator object, each time __next__ is called (), get the next generator content. Convert to corresponding container through list() and tuple().

Python generators save memory space because generator objects are returned instead of generating all the data at once.

The python generator is used in scenarios where multiple data can be calculated through a certain algorithm. It is not necessary to generate all the data at once, but to generate data on demand.

1.1 python generator function yield

Usage

def function name ([parameters]):
    ...
    yield expression
    ...

Description

NO Points Description
1 Composition The python generator function is a function containing a yield statement. Yield statements compile to generators.
2 Return Call the generator function to return the generator object. Because it contains the __next__() method, it is an iteration A container object that supports the iteration protocol and can be used in an iterative environment.
3 Execution Call the __next__() method to execute the function body, run to the yield statement to return the expression result, and The suspended function no longer executes the following statements; calls the __next__() method again, returns to the yield statement, continues to execute the following statements, runs again until the yield statement returns the result, and suspends the function; calls the __next__() method in a loop until The last item is completed and a StopIteration exception is raised.

Example

>>> def yieldF():
    print('Execute only once before starting for')
    for c in 'ladder lines':
        print('before yield')
        yield c
        print('after yield')
    print('Only executed once after the end of for')

>>> y=yieldF()
>>> type(y)
<class 'generator'>
>>> '__next__' in dir(y)
True
>>> t=y.__next__()
for is only executed once before starting
before yield
#Execute to the yield statement, return the expression result, stop execution and exit the function
>>> t #return expression result
'ladder'
>>> t=y.__next__()
#Call __next__ again to start execution from the statement after yield.
after yield
#Continue the for loop until the yield statement, return the expression result, and stop executing the exit function
before yield
>>> t
'read'
>>> t=y.__next__()
after yield
before yield
>>> t
'Wire'
>>> t=y.__next__()
after yield
before yield
>>> t
'strip'
>>> t=y.__next__()
after yield
#for loop ends
Execute only once after for ends
#Catch the exception yield end
Traceback (most recent call last):
  File "<pyshell#47>", line 1, in <module>
    t=y.__next__()
StopIteration

1.2 isgeneratorfunction()

Description

The python function isgeneratorfunction (function name) is used to determine whether a function is a generator function.

Example

>>> def isgf(n):
    for i in range(n):
        yield i
>>> list(isgf(3))
[0, 1, 2]
>>> from inspect import isgeneratorfunction as isg
>>> isg(isgf)
True
>>> isg(isgf(3))
False

1.3 Python stores yield value

Description

Python stores the value of the generator function yield expression as a list or tuple through the list() or tuple() function.

Example

>>> def yieldF():
    print('Execute only once before starting for')
    for c in 'ladder line':
        print('before yield')
        yield c
        print('after yield')
    print('Only executed once after the end of for')

>>>yl=list(y)
for is only executed once before starting
before yield
after yield
before yield
after yield
before yield
after yield
before yield
after yield
Execute only once after for ends
>>>yl
['ladder', 'reading', 'line', 'bar']

1.4 Python traverses yield items

Description

Python’s yield function generates an iterator object and supports iteration environments, such as traversing yield iteration items through a for loop.

Example

>>> def yieldF():
    print('Execute only once before starting for')
    for c in 'ladder line':
        print('before yield')
        yield c
        print('after yield')
    print('Only executed once after the end of for')
    
>>> y=yieldF()
>>> y=yieldF()
>>> for c in y:
    print('cbefore')
    print(c)
    print('after c')
#The for loop is an iteration tool and will automatically call the __next__() method of the iteration object.
#c returns the expression result for each yield call to the __next__() method
#The for loop automatically calls the __next__() method to execute the function body,
#When yield is encountered, store the expression result in c
for is only executed once before starting
before yield
before c
ladder
c after
after yield
before yield
before c
read
c after
after yield
before yield
before c
Wire
c after
after yield
before yield
before c
strip
c after
after yield
Execute only once after for ends

1.5 next method of python generator

Description

Python generator g.next() method, equivalent to next(g).

When the next method is called, the function body starts to be executed, execution is paused when the yield statement is reached, the expression result is returned, the next method is called again, and execution continues from the statement after yield until the yield statement or StopIteration exception is encountered.

Example

>>> def yieldF():
    print('Execute only once before starting for')
    for c in 'ladder line':
        print('before yield')
        yield c
        print('after yield')
    print('Only executed once after the end of for')

    
>>> y=yieldF()
>>> y.__next__()
for is only executed once before starting
before yield
'ladder'
>>> next(y)
after yield
before yield
'read'
>>> next(y)
after yield
before yield
'Wire'
>>> next(y)
after yield
before yield
'strip'
>>> next(y)
after yield
Execute only once after for ends
Traceback (most recent call last):
  File "<pyshell#25>", line 1, in <module>
    next(y)
StopIteration

1.6 send method of python generator

Usage

g.send(arg)

Description

The send() method of the Python generator object is similar to the __next__() method. It can return the next yield result and pause before continuing. At the same time, send(arg) can send arg to the variable after yield.

(1) For the first call, use send(None) or __next__() method.

If None is not sent for the first time, the following error will be reported. The variable is not set to receive the parameters when executing the function body.

TypeError*** can’t send non-None value to a just-started generator

(2) send(arg), returns the yield result, and sends arg to the variable after yield.

(3) Stop the generator or do other processing based on the arg value.

Example

>>> def yieldF():
    for c in 'ladder line':
        print('before yield')
        x=yield c
        print(x)
        print('after yield')
        
>>> y=yieldF()
>>> y.send('t')
Traceback (most recent call last):
  File "<pyshell#44>", line 1, in <module>
    y.send('t')
TypeError: can't send non-None value to a just-started generator
>>>y.send(None)
before yield
'ladder'
>>> y.send('y')
y
after yield
before yield
'read'
>>> next(y)
None
after yield
before yield
'Wire'
>>> y.send('t')
t
after yield
before yield
'strip'
>>> y.send('t')
t
after yield
Traceback (most recent call last):
  File "<pyshell#49>", line 1, in <module>
    y.send('t')
StopIteration

1.7 python uses yield to generate Fibonacci sequence

Description

The Fibonacci sequence is a recursive sequence. The first and second numbers are 1, and starting from the third number, each item is equal to the sum of the previous two items. This example generates the Fiatacci sequence through yield.

Example

>>> def fib(max):
    n,a,b=0,0,1
    while n<max:
        yield b
        a,b=b,a + b
        n=n+1
>>> list(fib(10))
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

1.8 python generator expression

Usage

(variable expression for variable in iteration object)

Description

Python’s generator expression is placed within parentheses and returns a generator object. Each time the next method is called, the expression result is returned.

Example

>>> gexp=(x*2 for x in range(10) if x%2==1)
>>> next(gexp)
2
>>> next(gexp)
6
>>> next(gexp)
10
>>> next(gexp)
14
>>> next(gexp)
18
>>> next(gexp)
Traceback (most recent call last):
  File "<pyshell#43>", line 1, in <module>
    next(gexp)
StopIteration
#The brackets of the generator can be omitted
>>> sum(x*2 for x in range(10) if x%2==1)
50
>>> sum((x*2 for x in range(10) if x%2==1))
50
>>> sorted(x*2 for x in range(10) if x%2==1)
[2, 6, 10, 14, 18]
#The brackets of the generator cannot be omitted
>>> sorted((x*2 for x in range(10) if x%2==1),reverse=True)
[18, 14, 10, 6, 2]

1.9 python generator is a single iteration object

Description

If the iterator returned by iter() is the object itself, it is a one-time iterator.

Python generator functions and generator expressions are one-time iterators, that is, single iteration objects.

Multiple iterators will execute the same iterator result. If any iterator completes, all iterators will complete.

The iterator must be regenerated for use.

Example

>>> g=(x*2 for x in 'ladder line')
>>> iter(g) is g
True
>>> g1,g2=iter(g),iter(g)
>>> next(g1),next(g2)
('Titi', 'Yueyue')
>>> next(g1),next(g2)
('line', 'bar')
>>> next(g1)
Traceback (most recent call last):
  File "<pyshell#62>", line 1, in <module>
    next(g1)
StopIteration
#Multiple iterators will execute the same iterator result. If any iterator is completed, all iterators will be completed.
>>> next(g2)
Traceback (most recent call last):
  File "<pyshell#63>", line 1, in <module>
    next(g2)
StopIteration
#The iterator must be regenerated for use.
>>> g=(x*2 for x in 'ladder line')
>>> g1,g2=iter(g),iter(g)
>>> next(g1),next(g2)
('Titi', 'Yueyue')