It does not generate the results stored in a series, but save the state generator, returns a value at each time iteration, until the encounter ends abnormally StopTteration
1, the generator syntax:
Generator expressions: syntax parsing through the list, but the list comprehension [] replace ()
Generator expressions can do basic list comprehension can handle, but when the sequence requires relatively large, relatively non-memory list comprehension
2, generator function:
appears yield keyword in the function, then the function is not in an ordinary function, but function generator
But the generator function can produce an infinite sequence, so there is no way to process the list
The role of yield is a function into a generator, with a yield function is no longer an ordinary function, Python interpreter will treat it as a generator
3、yield 与 return
When a return StopTterration Builder, if there is no return, the function is performed to complete the default
def gen(): yield 'a' >>> g = gen() >>> next(g) traceback (most recent call last): File"<stdin>", line 1, in <module> StopIterration
If the return is encountered in the implementation process, the direct termination of the iteration throws StopIteration
Gen DEF (): the yield ' A ' return the yield ' B ' >>> G = Gen () >>> Next (G) stays in the implementation of the program # play yield "a" position of the statement after the 'A' >>> Next (g) # when the program finds the next return statement, so throw StopTieration, so yield 'b' statement is never executed Traceback (MOST recent Results Last Call): File " <stdin> " , Line 1 , in <Module> StopIteraion
Supported methods generator
1、close()
Manual closing generator, directly behind the call returns StopIteration exception
>>> DEF Gen (): the yield . 1 the yield 2 the yield . 3 >>> G = Gen () >>> Next (G) . 1 after >>> g.close () # close the yield 2 and the yield . 3 statement will not in act Traceback (Last Call MOST): File " <stdin> " , Line . 1 , in <Module1> the StopIteration
2、send()
The greatest feature of the function generator is a variable can accept incoming external, variable according to the results returned content
This is where the generator function difficult to understand, is the most important place, it is thanks to him Ctrip
def gen(): value=0 while True: receive=yield value if receive=='e': break value = 'got: %s' % receive g=gen() print(g.send(None)) print(g.send('aaa')) print(g.send(3)) print(g.send('e'))
Implementation process:
1, the initiator can function by g.send (None) or next (g), and executes a first position at the end yield statements
At this point, execution over the yield statement, but not to receive an assignment, yield value will output initial value 0
2, by g.send ( 'aaa'), will pass aaa, and assigned to receive, and then calculate the value of value, while the head and back, do yield value statement has stopped
At this time, the output will yield value '' got 'aaa, and then hangs
3, g.send through (3), repeat the second step, the final output is "got:" 3
4, when we g.send ( 'e'), and then break the program execution exits the loop, and finally the entire function is finished, the exception will be StopItration
0 got: aaa got: 3 Traceback (most recent call last): File "h.py", line 14, in <module> print(g.send('e')) StopIteration
3、throw()
It is fed to a function generator to the exception and to be system-defined ends abnormally, or custom exception
throw (after) the end of direct rule out abnormal procedure. A consumed or yield, or directly to the end of the program in the absence of a time yiled
def gen(): while True: try: yield 'normal value' yield 'normal value 2' print('here') except ValueError: print('we got ValueError here') except TypeError: break g=gen() print(next(g)) print(g.throw(ValueError)) print(next(g)) print(g.throw(TypeError))
The output is:
normal value we got ValueError here normal value normal value 2 Traceback (most recent call last): File "h.py", line 15, in <module> print(g.throw(TypeError)) StopIteration
Implementation process:
1, print (next (g)): outputs Normal value, and remain in the yield 'normal value' before
2, due to the implementation of g.throw (TypeError), it will try to skip all subsequent statement, that "yield 'normal value2'" will not be executed, the statement except to let enter, print out we got ValueError here
Then re-enter the while loop part, consumed a yield, it will output normal value
3, print (next (g)), will perform yield normal value2 statement, and the rest position after the hi-line statement below
4, g.throw (TypeError): try statement will jump out, so print ( 'here') will not be carried out of the while loop, then to the end of the program, so raise StopIteration
Comprehensive example, the list expands a multi-dimensional, multi-dimensional or flat list
def flatten(nested): try: #如果是字符串,那么手动抛出TypeError。 if isinstance(nested, str): raise TypeError for sublist in nested: #yield flatten(sublist) for element in flatten(sublist): #yield element print('got:', element) except TypeError: #print('here') yield nested L=['aaadf',[1,2,3],2,4,[5,[6,[8,[9]],'ddf'],7]] for num in flatten(L): print(num)
4、yield from
yield is a function of generating an iterator, the us it will usually be placed in the loop output, sometimes we need to produce this iterator yield in a function generator, the generator is nested.
The following example:
def inner(): for i in range(10): yield i def outer(): g_inner=inner() #这是一个生成器 while True: res = g_inner.send(None) yield res g_outer=outer() while True: try: print(g_outer.send(None)) except StopIteration: break
There are two very good article written by:
http://blog.theerrorlog.com/yield-from-in-python-3.html
http://stackoverflow.com/questions/9708902/in-practice-what-are-the-main-uses-for-the-new-yield-from-syntax-in-python-3
to sum up
1, in accordance with the duck model theory, the iterator is a kind of generator, may be used for loop iteration
2, the first execution next (generator), will be executed after completion of the yield statement suspends program, all the parameters and the state saved
Once again, when executed next (generator), will start from the next execution suspended state
In the face of the end of the program or StopIteration, ending cycle
3, by generator. send (arg); parameters passed in this model is coroutine
4, by generator. throw (exception) to pass an exception, throw statement will consume a yield
By generator. close () Close the generator manually
5, next () equivalent to send (None)