Note: The next() method of generator is next() in python 2, but in python 3 it is __next__()
[next is preceded and followed by two underscores]
Turn a function into a generator. The function with yield is no longer an ordinary function. That is: a function with yield is a generator. It is different from an ordinary function. Generating a generator looks like a function call, but will not execute any function code until next() is called on it (it will be automatically called in a for loop next()) starts execution. Although the execution flow is still executed according to the flow of the function, every time a yield statement is executed, it will be interrupted and an iteration value will be returned. The next execution will continue from the next statement of yield. It looks like a function is interrupted several times by yield during normal execution, and each interruption returns the current iteration value through yield.
The benefits of yield are obvious. By rewriting a function as a generator, you gain the ability to iterate. Compared with using an instance of a class to save the state to calculate the value of the next next(), not only the code is concise, but the execution process is also simpler. Extraordinarily clear.
#!/usr/bin/env python # -*- coding: utf-8 -*-def fab(max): n , a, b = 0, 0 , 1 while n < max: print(b) a, b = b, a + b n = n + 1if __name__ == '__main__': fab(6) # 1 1 2 3 5 8
#!/usr/bin/env python # -*- coding: utf-8 -*-def fab(max): n , a, b = 0, 0 , 1 while n < max: yield b a, b = b, a + b n = n + 1if __name__ == '__main__': for n in fab(6): # 1 1 2 3 5 8 print(n)
#!/usr/bin/env python # -*- coding: utf-8 -*-from inspect import isgeneratorfunction def fab(max): n , a, b = 0, 0 , 1 while n < max: yield b a, b = b, a + b n = n + 1if __name__ == '__main__': f1 = fab(3) # True fab是一个generator function print(isgeneratorfunction(fab)) # False fab(3)不是一个generator function # 而fab(3)是调用fab返回的一个generator print(isgeneratorfunction(fab(3)))
#!/usr/bin/env python # -*- coding: utf-8 -*-def read_file(fpath): BLOCK_SIZE = 100 with open(fpath, "rb") as f: while True: block = f.read(BLOCK_SIZE) if block: yield block else: returnif __name__ == '__main__': fpath = "/home/exercise-python3.7.1/vote/mysite/mysite/polls/test.txt" read_gen = read_file(fpath) print(read_gen.__next__()) print(read_gen.__next__()) print(read_gen.__next__()) print(read_gen.__next__()) # for循环会自动调用generatr的__next__()方法,故输出效果同如上的4个print 【内容较短,4个print就将test.txt中的内容输出完了】 for data in read_gen: print(data)
#!/usr/bin/env python # -*- coding: utf-8 -*-if __name__ == '__main__': astr = "ABC" alist = [1, 2, 3] adict = {"name": "wangbm", "age": 18} # generate agen = (i for i in range(4, 8)) def gen(*args, **kw): for item in args: for i in item: yield i new_list = gen(astr, alist, adict, agen) print(list(new_list)) # ['A', 'B', 'C', 1, 2, 3, 'name', 'age', 4, 5, 6, 7]
#!/usr/bin/env python # -*- coding: utf-8 -*-if __name__ == '__main__': astr = "ABC" alist = [1, 2, 3] adict = {"name": "wangbm", "age": 18} # generate agen = (i for i in range(4, 8)) def gen(*args, **kw): for item in args: yield from item new_list = gen(astr, alist, adict, agen) print(list(new_list)) # ['A', 'B', 'C', 1, 2, 3, 'name', 'age', 4, 5, 6, 7]
Conclusion:
Comparing the above two methods, it can be seen that adding an iterable object after yield from can convert each item in the iterable object The elements yield one by one. Compared with yield, the code is more concise and the structure is clearer.
Related learning recommendations: python video tutorial
The above is the detailed content of python yield and yield from usage summary and detailed explanation. For more information, please follow other related articles on the PHP Chinese website!