python进阶学习(一)-生成器

    科技2024-04-21  10

    要了解生成器,首先需要明白三个概念:

    迭代(Iteration):如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历称为迭代(Iteration)。在Python中,迭代是通过for … in来完成的可迭代对象(Iterable):ython中任意的对象,只要它定义了可以返回一个迭代器的__iter__方法,或者定义了可以支持下标索引的__getitem__方法。一般是一些数据类型,比如list,tuple,dict,str,set等,这些可以直接作用于for循环的对象统称为可迭代对象。int类型是不可迭代对象。那么,如何判断一个对象是可迭代对象呢?方法是通过collections模块的Iterable类型判断: >>>from collections import Iterable >>>isinstance('abc', Iterable) True >>>isinstance(123, Iterable) False 迭代器(Iterator):可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。可以使用isinstance()判断一个对象是否是Iterator对象: >>>from collections.abc import Iterator >>>isinstance((x for x in range(10)), Iterator) #生成器 True >>>isinstance([], Iterator) False >>>isinstance({}, Iterator) False >>>isinstance('abc', Iterator) False

    list、dict、str虽然是Iterable,却不是Iterator。把list、dict、str等Iterable变成Iterator可以使用iter()函数:

    >>> isinstance(iter([]), Iterator) True >>> isinstance(iter('abc'), Iterator) True

    通过列表生成式,可以直接创建一个列表L = [x * x for x in range(10)]。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。 所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。 以计算斐波那契数列的生成器为例:

    def fibon(n): a = b = 1 for i in range(n): yield a a, b = b, a + b

    当调用生成器函数方法时,不会一次性将fibon(1000)所有的值计算出来tieda并存储,而是每迭代一次就计算一次,非常节省内存资源。

    for x in fibon(1000): print(x)

    生成器最佳应用场景是:你不想同一时间将所有计算出来的大量结果集分配到内存当中。

    廖雪峰的官方网站杨辉三角练习题,杨辉三角定义如下:

    把每一行看做一个list,试写一个generator,不断输出下一行的list:

    def triangles(): t = [1] while True: yield t t = [1] + [t[x]+t[x+1] for x in range(len(t)-1)] + [1] #上一行去掉第一个值和最后一个值,本行当前值=上一行当前位置+上一行的下一位置 n = 0 results = [] for t in triangles(): results.append(t) n = n + 1 if n == 10: break for t in results: print(t) >>>output: [1] [1, 1] [1, 2, 1] [1, 3, 3, 1] [1, 4, 6, 4, 1] [1, 5, 10, 10, 5, 1] [1, 6, 15, 20, 15, 6, 1] [1, 7, 21, 35, 35, 21, 7, 1] [1, 8, 28, 56, 70, 56, 28, 8, 1] [1, 9, 36, 84, 126, 126, 84, 36, 9, 1]

    注:普通函数和generator生成器的区别: 1.普通函数调用直接返回结果,generator函数的调用,返回一个generator对象;(调用generator时可以先创建一个对象,再用next()方法不断获得下一个返回值,但实际中通常用for循环实现) 2.generator在执行过程中,遇到yield就中断,下次又继续执行

    参考:https://www.liaoxuefeng.com/wiki/1016959663602400/1017318207388128 https://docs.pythontab.com/interpy/Generators/Generators/

    Processed: 0.050, SQL: 9