Python: Generator

Source: Internet
Author: User

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

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.