金沙官网线上廖雪峰老师博客学习《通过生成器

def theGe():
    i = 1
    yield i

print(type(theGe()))
    1. 从产生和存放杨辉三角的角度,来说说generator:triangles()函数完全可以不用yield,例如通过一个行数参数打印输出一个杨辉三角(这就需要在一个变量来存放一个完整的杨辉三角,最后再return整个杨辉三角)。使用yield,函数就返回了一个生成器对象,这个对象又是可迭代的,通过迭代再输出杨辉三角。前者通过函数时就生成了杨辉三角存放到内存中,然后从打印输出;后者这是一边生成一遍输出,根本就没有在内存中存放完整的杨辉三角。可以说生成器就是节约内存存储空间
    2. 看到上面,有人就会说了,就算不是使用生成器,将函数只返回指定的行,然后再循环调用输出,就不用在内存中存放一个完整的。确实,但是生成器还有一个特点就是可迭代,直接就可以用for 语句,那就是可迭代的优点了。
    3. 金沙官网线上,初学 者能力有限,感觉自己也没真正解剖出来。

 

    def triangles():
        lt = [1]
        while True:
            yield lt
            if lt.__len__() == 1:
                lt.append(1)
            else:
                len = lt.__len__()
                tmplist = [v for v in range(len-1)]   #构建一个临时列表,临时列表相较于最后生成,去掉了头尾。
                for n in range(len-1):
                    tmplist[n] = lt[n] + lt[n+1]
                lt = [1] + tmplist + [1]


    if __name__ == '__main__':
        g = triangles()
        for i in range(10):
            print(next(g))

-   运行结果

[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]

而下面这段代码

  • 思路:
    • 首先,杨辉三角,除了第一行和第二行之间没发现规律,就已特例直接产生
    • 然后,从第三行开始,出去头尾的元素,中间元素是前一行列表元素两两的和,那么我就构造一个中间元素的临时列表,然后根据前一行列表产生临时列表的值
    • 最后,给中间元素列表头尾添加上[1],这样就产生了后续列表的算法。
  • 别人的思路:网上的思路是发现这样一个算法规律:后一行是用前一行构造两个分别是头尾加上[0]的列表,然后两个列表zip()一下。就得到需求列表。
    • 思路不同,用到的实现手法就不同。
    • 见识了zip()的应用。什么叫人生苦短,****!
    • 自己的思路就没那么简洁。
  • 解剖一下和生成器generator有什么好处(比较表面):
L3  = []
for i in range(len(L2)):
    L3.append(L2[i-1] + L2[i])

6、函数结束时,抛出StopIteration异常。

2、对内存更加友好.例如:我们创建一个列表的时候,是一创建就存放到内存中的,如果数据量很大,毫无疑问会占用大量内存(而很多时候,我们可能并不需要访问所有数据)。如果列表元素可以通过某种算法推算出来,一边循环一边计算,这样就能节省大量的内存。Python的生成器就可以实现这种功能.

其实就是:

1 L3  = []
2 # 列表的索引为-1的时候,值=0. L2[-1] = 0
3 L3.append(L2[-1] + L2[0])
4 L3.append(L2[0]+L2[1])
5 L3.append(L2[1]+L2[2])

1、Generator函数包含一个或多个yield语句。

(一)生成器(Generator)

例如:我们知道第二行的元素,我们可以通过下面这种方式获得三行的元素(这个规律是通用的)

列表生成式:

可以看到,print('生成器:',theGe)输出的是一个生成器对象,不会直接输出结果

下面这段代码的效果和上面的列表生成式是一样的(一开始可能不太习惯列表生成式的写法,多写几次就习惯了):

2、在函数中定义yield语句就行了(执行到yield语句时,就会返回结果,不过生成器函数和普通函数还是有区别的,下面会说明)

(五)使用生成器的优势

5、局部变量和状态会被保存,一直到下一次调用。

金沙官网线上 1

1、易于实现,代码更简洁,容易阅读。(例如:使用迭代器我们需要自己去定义__iter__()和_next_()方法,而生成器会自动处理这些

因为下面会用到列表生成式,这里先说明下列表生成式:

金沙官网线上 2

1 L3  = [L2[i-1]+L2[i] for i in range(len(L2))]
theLi = [i*i for i in range(10)]

1、将列表生成式的[]换成()就行了。

本文由金沙官网线上发布于编程,转载请注明出处:金沙官网线上廖雪峰老师博客学习《通过生成器

您可能还会对下面的文章感兴趣: