1. Generator object
- Definition: a generator is actually a special iterator, which can be called a user-defined iterator. The definition stage is an ordinary function. The function is turned into a generator only when it is called. When calling a function for the first time, the function body code will not be executed, but only conversion.
- Keyword: yield
- As long as there is a yield keyword in the function, it is a generator!
Examples are as follows:
# def my_range(start,stop = None,step=1): # if stop ==None: # stop,start = start,0 # # start = 0 # while start<stop: # yield start # start+=step # # Convert function names into iterators with parentheses # for i in my_range(0,10,2): # print(i) # for i in range(1,10): # print(i) # Generator yield # Define stage as normal function def build(): print('First call') yield 'stay yield You can also write the return value later!' print('Second call') yield 'stay yield You can also write the return value later!' # The calling function does not execute code, but is transformed into a generator build() # Receive by traversing res res = build() # Output through the next() function. Note that calling the next() function matches the number of lines of code ret = res.__next__() # There is only one print statement, and an error is reported when calling next() # ret = res.__next__() # Printing ret is to get the return value of yield print(ret) '''Every call next()Function, the code will automatically stop at yield，And return the following values. Calling again will follow the last execution''' res.__next__()
Exercise: customizing the range function
Implement the function of 1:1 restore range() and use the generator object
First, recall the range function structure, range (start, stop, step)
Examples are as follows:
# for loop traversal implementation 1-10 for i in range(1,10): print(i) # Custom range() function # Write parameters according to range def my_range(start,stop = None,step=1): # If only one value is entered, the end value is the starting value if stop == None: stop,start = start,0 # Traversal output while start<stop: yield start # Realize step function start+=step # Convert function names into iterators with parentheses for i in my_range(0,10,2): print(i) '''The result is the same!'''
yield value
Using the send() function, you can avoid multiple writes after yield
def doing(name): print(f'{name}Get up!') while True: some_wh = yield print(f'{name}go{some_wh}') # The first call is converted to a generator without executing the code res = doing('HammerZe') res.__next__() # Pass value with send() res.send('Beijing') res.send('Shanghai') res.send('Guangzhou') # result # HammerZe, get up! # HammerZe to Beijing # HammerZe to Shanghai # HammerZe to Guangzhou
Through the above examples, we can find that the function of yield is very similar to that of return. The similarities and differences between yield and return are as follows:
Similarities:
- Can return one or more values (when multiple values are organized into meta groups)
difference:
- When the function encounters yield, it will not end, but "stop". The next call will be executed. return directly ends the function!
- yield can turn the function into a generator, support value passing, and use the send() function
2. Generator expression
How do I create a generator?
- As mentioned in the previous article of list generation, the generator here only needs to change the brackets of list generation into parentheses.
How do I get the elements of the generator? There are two ways
for loop / list traversal
The next () function iterates through it in turn
Examples are as follows:
# Create a list generator l = [i for i in range(10)] print(l) # Convert to generator l1 = (i for i in range(10)) # The generator can only be executed through traversal. The following are the three methods of traversal for j in l1: # Or list(l1) print(j) l2 = (i for i in range(10)) print(l2.__next__()) print(l2.__next__()) print(l2.__next__()) # result [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 0 1 2 3 4 5 6 7 8 9 0 1 2
Both the generator object and the iterator object use the next () function once to print a sentence. The advantage of the generator is that it can calculate and cycle at the same time. The use of the generator saves space!
Exercise: output res results (PIT)
Examples are as follows:
# Sum def add(n, i): return n + i # The call is preceded by a function call and followed by a generator def test(): for i in range(4): yield i g = test() # Initialize generator object for n in [1, 10]: # Pit!!! g = (add(n, i) for i in g) """ for the first time for loop g = (add(n, i) for i in g) The second time for loop g = (add(10, i) for i in (add(10, i) for i in g)) """ # Here, g takes n from the last traversal and passes it in for calculation, n = 10 res = list(g) print(res) #result [20, 21, 22, 23]
Let's guess the result of res. it is not allowed to execute. Don't peek at the result (pretend not to see it). The options are as follows:
A. res=[10,11,12,13] B. res=[11,12,13,14]
C. res=[20,21,22,23] D. res=[21,22,23,24]
If there are any errors, please correct them. Thank you. They are constantly updated·····