要说生成器,就必须首先要知道列表的概念;

我们创建一个如下的列表:

ls = [1,2,3,4,5,6,7,8,9]

那么就开辟了一个门牌号为ls的内存区,然后真的把1,2,3,4,5,6,7,8,9这几个数字放到了内存中;

如果我们在for循环中要根据i的值来获取一个值的话,我们可以把数据放在上面的ls中,然后通过ls[i]来获取;这样的

方式存在巨大的缺点,就是要事先准备好ls中的所有数值;如果很多的话会造成响应慢,内存溢出等问题;

所以就有有了生成器的概念,生成器会指定一个公式,然后每次循环都根据公式计算出当前的值,不用事先生成

所有的值。

一、最简单的生成器

# -*- coding:utf-8 -*-
# Author: Evan Mi# 这是一个最基本的生成器,对应的公式是i*2,i从0到9
# 这样我们就可以通过迭代的方式来访问生成的每一个值了
# 它的缺点就是,只能逐一迭代,不能随意指定i,也不能往前迭代
my_gen_01 = (i*2 for i in range(10))
"""
可以看到my_gen是一个generator对象
"""
print(my_gen_01)  # <generator object <genexpr> at 0x00000000024FCBA0>
#   generator对象是一个迭代器对象,所以直接通过next()方法来迭代
while True:try:print(next(my_gen_01))     # 迭代(根据公式计算)except StopIteration as e:  # 迭代到没有元素后会抛出StopIterationprint(e.value)break
"""
运行结果:
0
2
4
6
8
10
12
14
16
18
None
"""
#   用for循环迭代,不会有异常抛出
#   需要新建一个,因为上一个已经被迭代完了(生成器是一次性用品)
my_gen_02 = (i*2 for i in range(10))for val in my_gen_02:print(val)
"""
运行结果:
0
2
4
6
8
10
12
14
16
18
"""

二、用函数来实现复杂的生成器

# -*- coding:utf-8 -*-
# Author: Evan Mi# 引用别人的斐波那契数列生成函数
"""函数运行到yield的时候,就会暂停,并将yield关键字之后的值传到函数外,函数暂停在这里,直到等到下一次迭代"""
def fib(max_num):n, a, b = 0, 0, 1while n < max_num:yield ba, b = b, a+bn += 1# 定义了一个生成器,这个生成器每次迭代得到的值就是yield带出来的值fb = fib(10)#  用for循环迭代
for val in fb:print(val)
"""
运行结果:
1
1
2
3
5
8
13
21
34
55
"""
# 用next迭代
fb1 = fib(10)
while True:try:print(next(fb1))except StopIteration as e:print(e.value)break
"""
运行结果:
1
1
2
3
5
8
13
21
34
55
None
"""

可以看到,在使用for循环迭代的时候,并不需要自己去处理迭代停止的异常;而用next自己处理就需要;而且

我们每次的e.value都是none;现在给函数加上返回值,如下:

def fib(max_num):n, a, b = 0, 0, 1while n < max_num:yield ba, b = b, a+bn += 1return 'done'

对这样的函数,我们用next调用;

# 用next迭代
fb1 = fib(10)
while True:try:print(next(fb1))except StopIteration as e:print(e.value)break
"""
运行结果:
1
1
2
3
5
8
13
21
34
55
done
"""

可以看到e.value变成了done;所以一个函数如果作为了生成器,那么return的值就是迭代停止时的异常信息;

yield能带出函数中的值,那么yield就是函数内部与外界的媒介,那么自然也能从外部代值回来:

修改函数如下:

def fib(max_num):n, a, b = 0, 0, 1while n < max_num:xxx = yield b  # 后面的b在运行到yield时被带出去,前面的xx在激活yield时被带进来print(xxx)a, b = b, a+bn += 1return 'done'

执行如下的测试:

gx = fib(10)
# 一开是只能调用next,因为这时只是创建了一个生成器,还没有yield变量
print('out;', next(gx))
# 把233给yield,同时往下运行到下一次循环到yield处,并带回yield的值
print('out;', gx.send(233))
print('out;', gx.send(333))
print('out;', gx.send(433))
# 循环到下一次的yield,并带回yield的值(其实就是把None给了yield)
print('out;', next(gx))

运行结果如下:

out; 1  第一次只能从yield带出值
233    通过yield传入了233,在函数内部打印
out; 1    带出1
333    传入333
out; 2 带出2
433 传入433
out; 3 带出3
None 传入None
out; 5 带出5

python3 生成器相关推荐

  1. python3生成器_Python3 生成器

    Python3 生成器 阅读 (125) | 发布于 2020-05-19 14:29:25 在Python中,一边循环一边计算出元素的机制,称为生成器:generator. 生成器的优点:一次返回一 ...

  2. python3生成器与迭代器_Python3迭代器与生成器

    迭代器 迭代是Python最强大的功能之一,是访问集合元素的一种方式. 迭代器是一个可以记住遍历的位置的对象. 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退 ...

  3. python3生成器_Python3.7之生成器

    Python3.7之生成器 一.生成器概念 Python使用生成器对延迟操作提供了支持.所谓延迟操作,是指在需要的时候才产生结果,而不是立即产生结果.主要有两种结构可以延迟结果创建.生成器函数和生成器 ...

  4. python3 生成器_python3基础之生成器

    初识生成器 说到生成器还是要从列表推导式说起,关于列表推导式可以看看<python3基础之如何使用列表推导式>.先看一个简单的列表推导式: 可以看到列表推导式是用中括号将式子括起来的,如果 ...

  5. python3生成器与迭代器_python3迭代器和生成器 | 吴老二

    迭代函数就是一个利用for...in来完成的一个过程,但是呢?在没说迭代函数之前我们需要了解一下什么是迭代器,什么是生成器,两者的区别是什么,先一个一个的学习. 迭代器 先学习一下什么是迭代器,迭代器 ...

  6. python3生成器函数_Python 3 之 生成器详解

    ------ 生成器 ------------------------------------------------------------------ 如今Python对延迟提供更多的支持--它提 ...

  7. python3 生成器_python3之迭代器和生成器

    python3之迭代器和生成器 一.迭代器 一) 迭代 重复多次,可以用 for-in 循环 字符串,元组,列表,字典,range都是可迭代的,但不是迭代器,可用来创建迭代器 二) 迭代器 包含 __ ...

  8. python3 生成器的send_Python:生成器中send()的行为

    我在 python 3中尝试使用生成器并编写了这个相当人为的生成器: def send_gen(): print(" send_gen(): will yield 1") x = ...

  9. python3生成器类题目易错写法

    遍历 定义一个生成器列表 a = [(i for i in range(10))] 使用for遍历 for i in a:print(i) # <generator object <gen ...

最新文章

  1. java中怎样判断余数为3,Java的基础语法(三): 运算符
  2. 2019微信年度报告!!!
  3. Kotlin-Learning 扩展
  4. @Autowired和@Resouce的区别
  5. python tempfile 创建临时目录
  6. 关于调试过程中单片机复位的几点心得与体会
  7. IDEA 的 debug 怎么实现?出于这个好奇心,我越挖越深!
  8. 嵌入式Linux系统编程学习之二十三 System V 共享内存机制
  9. mysql做主从分离后插入更新过慢
  10. oracle 11g压缩分区表,ORACLE 10g和11g压缩分区表操作脚本
  11. 威纶触摸屏与三菱D700变频器485通讯程序 自己编写的威纶触摸屏与台达变频器的通讯程序
  12. 使用 OpenSSL 创建ssl自签名证书
  13. oracle加减乘除怎么写,加减乘除怎么写-加减乘除的名称怎么写-加减乘除的笔画怎么写...
  14. 【动态规划】黑熊过河
  15. caffe 6中优化方法并附带 对应的solver。prototxt代码
  16. 八皇后问题 回溯法
  17. html仿今日头条数据列表
  18. 这五个姓氏你根本没见过,第三个甚至难以启齿
  19. 养殖专家告诉你在农村养啥赚钱
  20. 20220530-动态规划算法及Needleman-Wunsch算法

热门文章

  1. 2021年香河一中高考成绩查询,2021年廊坊高考状元名单公布,廊坊文理科状元是谁多少分...
  2. java将属性练成字符串,Java中通过属性字符串名取属性内容
  3. 萤石云设备下线是什么导致的_什么原因导致化工设备腐蚀?腐蚀防护措施有哪些?...
  4. 基于Java+SpringMvc+vue+element实现上海汽车博物馆平台
  5. linux ssh 插件,玩转VSCode插件之Remote-SSH的使用情况
  6. MySQL 常用运算符
  7. 滑动加载怎么做 php,vue之UI框架如何实现滑动加载数据
  8. 买电脑主要看什么配置_买笔记本电脑主要看什么? 配置要什么样的才算好?...
  9. core mysql 延迟加载_mybatis延迟加载及实例讲解
  10. 【商业】10个经济学概念,让你看清复杂世界