专栏首页赖权华的笔记Python笔记(十七):生成器

Python笔记(十七):生成器

(一)生成器(Generator)

Python生成器是创建迭代器的简单方法。简单来说,生成器是一个函数,它返回一个我们可以迭代的对象(迭代器)(一次一个值)。

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

列表生成式:

theLi = [i*i for i in range(10)]

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

L = []
for i in range(10):
    L.append(i*i)

可在IDE中将结果打印出来. 

(二)创建生成器

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

1 theLi = [i*i for i in range(10)]
2 
3 print(theLi)
4 #创建一个生成器
5 theGe = (i*i for i in range(10))
6 
7 print('生成器:',theGe)

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

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

def theGe():
    i = 1
    yield i

print(type(theGe()))

(三)生成器函数和普通函数的区别

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

2、调用生成器函数时,它返回一个生成器对象,但不会立即执行。

3、生成器函数会自动实现__iter__()__next__()方法。

4、执行顺序不同:普通函数执行到最后一句或者return语句时,就返回结果.而生成器函数,则是每次调用next()方法时执行,遇到yied语句就返回结果,再次执行时从上次结束的yield语句处开始执行.(执行顺序的问题,设个断点运行一次就清楚了)。

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

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

举个例子:

 1 from collections import Iterable
 2 from collections import Iterator
 3 
 4 def gen():
 5 
 6     i = 1
 7     print('第一次:',end='')
 8     yield i
 9     i += 1
10     print('第二次:',end='')
11     yield i
12     i += 1
13     print('第三次:',end='')
14     yield i
15 
16 print(type(gen()))
17 #生成器也是迭代器
18 print(isinstance(gen(),Iterable))
19 print(isinstance(gen(),Iterator))
20 
21 g = gen()
22 print(next(g))
23 print(next(g))
24 print(next(g))
25 print(next(g))

(四)生成器的使用

例如:使用生成器实现杨辉三角

比较简单的一种理解方式,将每一行都看成一个列表,通过末尾补0的方式来计算下一行列表的值.

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

 1 #第二行
 2 L2 = [1,1]
 3 
 4 L2.append(0) #此时变成了[1,1,0]
 5 
 6 
 7 L3  = []
 8 # 列表的索引为-1的时候,值=0. L2[-1] = 0
 9 L3.append(L2[-1] + L2[0])
10 L3.append(L2[0]+L2[1])
11 L3.append(L2[1]+L2[2])
12 
13 print(L3)

而下面这段代码

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

其实就是:

L3  = []
for i in range(len(L2)):
    L3.append(L2[i-1] + L2[i])

也是(列表生成式的写法):

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

实现杨辉三角:

 1 #杨辉三角
 2 def yhTriangles(n):
 3     yh = [1]
 4     while len(yh) <= n:
 5         yield yh
 6         yh.append(0)
 7         yh = [yh[i-1] + yh[i] for i in range(len(yh))]
 8 
 9 
10 for i in yhTriangles(10):
11     print(i)

(五)使用生成器的优势

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

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

3、生成器可以代表一个无限的数据流.(无限的数据流是不能直接存放到内存中的,因为内存是有限的)

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Python网络爬虫笔记(二):链接爬虫和下载限速

    (一)代码1(link_crawler()和get_links()实现链接爬虫) 1 import urllib.request as ure 2 impo...

    free赖权华
  • loadrunner笔记(一):下载、安装loadrunner和负载压力测试概念说明

    free赖权华
  • Python Django框架笔记(五):模型

    free赖权华
  • JavaScript 编程规范(二)

    1. 总是使用 const 或 let 来声明变量。 不这样做会导致产生全局变量。 我们希望避免污染全局命名空间。

    桃翁
  • 随机点名系统——html初学实战

    接着导入每一个节点元素,innerHTML为相应名字,样式与设置参数一样,类名为name

    glm233
  • 用uid分库,uname上的查询怎么办?

    1分钟系列 【缘起】 用户中心是几乎每一个公司必备的基础服务,用户注册、登录、信息查询与修改都离不开用户中心。 当数据量越来越大时,需要多用户中心进行水平切分。...

    架构师之路
  • python 列表(增删改查)

    py3study
  • 用命令行的方式运行Spark平台的wordcount项目

    local模式运行非常简单,只要运行以下命令即可,假设当前目录是$SPARK_HOME MASTER=local bin/spark-shell “MAST...

    Jerry Wang
  • 三星收购了西班牙AI网络分析公司Zhilabs,以加速发展AI和5G

    三星宣布收购西班牙网络分析公司Zhilabs,该公司利用AI监控运营商的网络性能和无数服务的数据流量。该交易的条款没有披露。

    AiTechYun
  • 微软 Windows 系统检测网络连通性(用于显示感叹号)竟然是通过访问一个特殊网址来实现的

    2018-06-06 02:27

    walterlv

扫码关注云+社区

领取腾讯云代金券