The builder is one of the most attractive features of the Python language, and the generator is a special kind of iterator, but it's more elegant. It does not need to write the __iter__ () and __next__ () methods as in the class above, only one yiled keyword is required.
Iterate through the list of all the words in the nested list provided, and then iterate through the elements in the list sequentially. Any function that contains a yield statement is called a generator. In addition to the name of the unexpected, its behavior and the normal function is also very different, this is that it does not return the value as returned, but each time to produce multiple values. Each time a value is generated (using the yield statement), the function is frozen: that is, the function stops at that point and waits to be activated, and the function is activated to execute from the point where it was stopped.
Nested=[[1,2],[3,4],[5]]defFlatten (nested): forSublistinchNested: forElementinchsublist:yieldelement forNuminchFlatten (nested):Print(num)#1#2#3#4#5Print(List (flatten (nested)))#[1, 2, 3, 4, 5]
Generator two ways of creating
1. (X*2 for X in range (3))
#a=[x*2 for x in range (1000000)] #不要试, freezingS= (x*2 forXinchRange (3))Print(s)#<generator Object <genexpr> at 0x00000203201e6938>Print(Next (s))#equivalent to print (s.__next__ ()), in Py2:s.next ()Print(Next (s))Print(Next (s))Print(Next (s))#stopiteration#The generator is an iterative object (iterable)
2.yield Builder Object
The generator is a function that contains the yield keyword. When it is called, the code in the body of the function is not executed, and an iterator is returned. Each time a value is requested, the code in the generator executes, knowing that the yield or return statement is encountered.
The yield statement means that a value should be generated, and the return statement means that the generator will stop executing (nothing is generated and the return statement can be called without arguments only when used in a generator). In other words, the generator is composed of two parts: the generator's function and the generator's iterator generator's functions are defined using the DEF statement, which contains the yield, which is the part of the function returned by the generator.
According to a not very accurate statement, two entities are often treated as a, together called generators. The generator function is only a little different from the normal function, which is to change the return to yield, where yield is a syntactic sugar that implements the iterator protocol internally, while keeping the state hanging.
deffoo ():Print("Hello World") yield1Print("OK") yield2foo ()#Builder object, no code executiong=foo ()Print(g)#<generator object foo at 0x00000230a33569e8>Next (g)#Hello WorldNext (g)#OK#Next (g) #StopIteration forIinchFoo ():#iterate over an iterative object that has the Iter method Print(i)#Hello World#1#OK#2
Example of a Fibonacci sequence using a generator: a
deffib (max): N, a, b= 0, 0, 1 whileN <Max:#print (b) yieldb A, b= B, A +B N= n + 1return ' Done'F=FIB (6)Print(f)#<generator object fib at 0x0000025839e56990>#The most difficult thing to understand here is that the generator is not the same as the execution flow of the function. #The function is executed sequentially, the return statement is encountered, or the last line function statement is returned. #The function that becomes generator is executed every time the next () is called, and the yield statement is returned,#Execution resumes from the yield statement that was last returned. Print(F.__next__())Print(F.__next__())Print("________*****______")Print(F.__next__())Print(F.__next__())Print(F.__next__())
Results:
1
1
________*****______
2
3
5
Two
deffib (max): N, a, b= 0, 0, 1 whileN <Max:#print (b) yieldb A, b= B, A +B N= n + 1return ' Done'F=FIB (6) whileTrue:Try: x=next (f)Print('F:', X)exceptstopiteration as E:Print("Generator return value:", E.value) Break#ResultsF:1F:1F:2F:3F:5F:8GeneratorreturnValue:done
The new property of the generator is the ability to provide a value to the generator after it has started running. A channel for communication between the generator and the "Outside world":
- The external scope accesses the generator's send method, just like the next method, except that it uses a parameter (the message that is sent---any object)
- Internally, the generator is suspended, yield is now used as an expression instead of a statement, in other words, when the generator is newly run, the yield method returns a value, which is the value sent externally by the Send method. If the next method is used, then the yield method returns none.
- The throw method (called with an exception type, with optional values and backtracking objects) is used to throw an exception within the generator (in the yield expression)
- The Close method, when not used with parameters, stops the generator.
def Bar ():
Print('Ok1') Count=yield1Print(count)yield2b=Bar () Next (b)#s=b.send (none) #next (b) If there is no next before the first send, only one send (none) can be sent#print (s)Ret=b.send ('Eee')Print(ret)#b.send (' FFF ')
Results:
Ok1
Eee
2
Send Working method
deff ():Print("OK") s=yield7Print(s)yield8F=f ()Print(F.send (None))#OK#7Print(Next (f))#None#8#Print ( f.send (None)) is equivalent to print (Next (f)) and executes the process: Print Ok,yield7, when next comes in: assigns None to S, and then returns 8, which can be observed by a breakpoint
Eat steamed bun Case
Import TimedefConsumer (name):Print("%s ready to eat buns!"%name) whileTrue:baozi=yield Print("Bun [%s] came, eaten by [%s]!"%(baozi,name))defproducer (name): C= Consumer ('A')#Builder ObjectC2 = Consumer ('B')#Builder ObjectC.__next__()#Execute GeneratorC2.__next__() Print("%s start preparing buns!"%name) forIinchRange (1,6,2): Time.sleep (1) Print("made 2 buns!") c.send (i) c2.send (i+1) Producer ("Greg")
Co-process applications:
The so-called Synergy program is that it can be suspended, resumed, and has multiple entry points. In fact, that is to say, multiple functions can be at the same time, you can send messages between each other.
ImportQueuedeftt (): forXinchRange (3): Print('TT'+str (x))yielddefGG (): forXinchRange (3): Print('xx'+str (x))yieldclassTask ():def __init__(self): Self._queue=queue. Queue ()defAdd (Self,gen): Self._queue.put (gen)defRun (self): while notself._queue.empty (): forIinchRange (Self._queue.qsize ()):Try: Gen=Self._queue.get () gen.send (None)exceptstopiteration:Pass Else: Self._queue.put (gen) T=Task () T.add (TT ()) T.add (GG ()) T.run ()#tt0#xx0#TT1#xx1#TT2#xx2
Python: Generator