Python 生成器 (generator) & 迭代器 (iterator)
python 生成器 & 迭代器
生成器 (generator)
列表生成式
列表生成式用来生成一个列表,虽然写的是表达式,但是储存的是计算出来的结果,因此生成的列表受到内存大小的限制
示例:
a = [x ** 2 for x in range(5)]
print(a)
输出结果:
[0, 1, 4, 9, 16]
生成器 (generator)
生成器同样可以用来生成一个列表,但是生成器保存的是算法,在每一次调用 next
时才会计算出结果,因此生成的列表不会受到内存大小的限制
示例:
a = (x ** 2 for x in range(5))
print(a)
for i in range(6):
print(next(a))
输出结果:
<generator object <genexpr> at 0x107da7870>
0
1
4
9
16
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
StopIteration
每次调用 next()
,就计算出下一个元素的值,无法再次获取前面元素的值,直到计算到最后一个元素,没有更多的元素时,抛出 StopIteration 的错误
生成器函数
当函数中出现 yield
时这个函数就成了一个 generator 的函数
generator 在执行的时候遇到 yield
时会暂停并保存当前所有的运行信息,返回 yield
的值, 并在下一次执行 next()
方法时从当前位置继续运行
示例:
def fib(max_n):
"""斐波那契数列生成器"""
n, a, b = 0, 0, 1
while n < max_n:
yield b
a, b = b, a + b
n = n + 1
return 'done'
def main():
f = fib(6)
while True:
try:
x = next(f)
print(x)
except StopIteration as e:
print("Generator return value:", e.value)
break
if __name__ == '__main__':
main()
输出结果:
1
1
2
3
5
8
Generator return value: done
通过 yield 实现在单线程的情况下实现并发运算的效果
示例:
import time
def consumer(name):
print("%s开始吃包子了" % name)
while True:
produce = yield # 函数在此暂停,等待唤醒
print("%s吃了第%i笼包子" % (name, produce+1)) # 唤醒后执行
def producer(name):
c = consumer("A")
c2 = consumer("B")
c.__next__()
c2.__next__()
print("%s准备开始生产" % name)
for i in range(3):
time.sleep(1)
print("已经做了%i笼包子" % (i+1))
c.send(i) # 将i发送给produce,并唤醒函数
c2.send(i)
producer("C")
输出结果:
A开始吃包子了
B开始吃包子了
C准备开始生产
已经做了1笼包子
A吃了第1笼包子
B吃了第1笼包子
已经做了2笼包子
A吃了第2笼包子
B吃了第2笼包子
已经做了3笼包子
A吃了第3笼包子
B吃了第3笼包子
在 producer 函数中 c 和 c2 轮流调用 consumer 函数
send()
和 next()
一样可以唤醒生成器,而且还能给 yield
传值
迭代器 (iterator)
可迭代对象 (iterable)
可以直接作用于 for 循环的数据类型有以下两种:
- 一类是集合数据类型,如 list、tuple、dict、set、str 等
- 一类是 generator,包括生成器和带 yield 的 generator function
这些可以直接作用于 for 循环的对象统称为可迭代对象
示例:
def fib(max_n):
"""斐波那契数列生成器"""
n, a, b = 0, 0, 1
while n < max_n:
yield b
a, b = b, a + b
n = n + 1
return 'done'
def main():
f = fib(6)
for i in f:
print(i)
if __name__ == '__main__':
main()
输出结果:
1
1
2
3
5
8
迭代器 (iterator)
可以被 next()
函数调用并不断返回下一个值的对象称为迭代器
生成器都是 Iterator 对象,但list、dict、str 虽然是 Iterable ,却不是Iterator
把list、dict、str 等 Iterable 变成 Iterator 可以使用 iter()
函数
示例:
a = [1, 2, 3, 4, 5, 6, 7]
b = a.__iter__()
c = iter(a)
print(a, b, c)
输出结果:
[1, 2, 3, 4, 5, 6, 7] <list_iterator object at 0x11d271f60> <list_iterator object at 0x11d260160>
b, c 都是通过 a 变成的迭代器
a, b, c 都可以使用 for 循环:
for i in a:
print(i)
for i in b:
print(i)
结果一致
对比
生成器 (generator) 都是迭代器 (iterator),但是迭代器不一定是生成器,还有通过 iter()
变成迭代器的可迭代对象
Python 生成器 (generator) & 迭代器 (iterator)的更多相关文章
- python生成器(generator)、迭代器(iterator)、可迭代对象(iterable)区别
三者联系 迭代器(iterator)是一个更抽象的概念,任何对象,如果它的类有next方法(next python3)和__iter__方法返回自己本身,即为迭代器 通常生成器是通过调用一个或多个yi ...
- 【python之路29】python生成器generator与迭代器
一.python生成器 python生成器原理: 只要函数中存在yield,则函数就变为生成器函数 #!usr/bin/env python # -*- coding:utf-8 -*- def xr ...
- python 生成器和迭代器有这篇就够了
本节主要记录一下列表生成式,生成器和迭代器的知识点 列表生成器 首先举个例子 现在有个需求,看列表 [0,1,2,3,4,5,6,7,8,9],要求你把列表里面的每个值加1,你怎么实现呢? 方法一(简 ...
- Python学习笔记 - 迭代器Iterator
我们已经知道,可以直接作用于for循环的数据类型有以下几种: 一类是集合数据类型,如list.tuple.dict.set.str等: 一类是generator,包括生成器和带yield的genera ...
- Python生成器,迭代器,可迭代对象
在了解Python的数据结构时,容器(container).可迭代对象(iterable).迭代器(iterator).生成器(generator).列表/集合/字典推导式(list,set,dict ...
- python 生成器和迭代器介绍
在正式接触生成器之前,我们先来了解一些概念 容器(container) 容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个迭代获取,可以用in.not in关键字判断元素是否包含在容器中. ...
- 【转】python 生成器和迭代器有这篇就够了
总结得特别好,转自:https://www.cnblogs.com/wj-1314/p/8490822.html 本节主要记录一下列表生成式,生成器和迭代器的知识点 列表生成器 首先举个例子 现在有个 ...
- python生成器、迭代器、__call__、闭包简单说明
1.生成器 这种一边循环一边计算的机制,称为生成器:generator,最简单的方法是把生成式的[]改为(). >>> l=(x * x for x in range(1, 11) ...
- Python 生成器与迭代器 yield 案例分析
前几天刚开始看 Python ,后因为项目突然到来,导致Python的学习搁置了几天.然后今天看回Python 发现 Yield 这个忽然想不起是干嘛用的了(所以,好记性不如烂笔头.).然后只能 花点 ...
随机推荐
- Change Style of Navigation Items 更改导航项的样式
In this lesson, you will learn how to change the style of navigation items in a WinForms XAF applica ...
- vs2017 输出 ling to sql 转为执行的sql语句
在项目视图中,找到->输出 窗口,在窗口中选择ASP.NET Core Web服务器,调试项目即可看到执行的sql语句
- Android8.1 源码修改之插入SIM卡默认启用Volte功能
前言 公用电话产品,插入SIM卡后要求自动打开Volte功能,即插即用,用完拔卡就走 实现 第一步 开关对应的代码 通过打印日志和全局查找,源码位置 vendor/mediatek/proprieta ...
- 苹果_公司开发者账号_注册Apple ID
本文所有网站入口为developer.apple.com 注册Apple ID 注意事项:目前注册信息尽量用拼音或英文,姓名格式正确,记住安全问题,出生日期在18岁以上(小于18岁会出现Sorry,y ...
- 理解 Flutter 中的 Key
概览 在 Flutter 中,大概大家都知道如何更新界面视图: 通过修改 Stata 去触发 Widget 重建,触发和更新的操作是 Flutter 框架做的. 但是有时即使修改了 State,Flu ...
- Android几种多渠道打包
1.什么是多渠道打包 在不同的应用市场可能有不同的统计需求,需要为每个应用市场发布一个安装包,这里就引出了Android的多渠道打包.在安装包中添加不同的标识,以此区分各个渠道,方便统计app在市场的 ...
- Linux tree
tree命令,是大小写敏感的.常用的是:1.tree -C 颜色显示 2.tree -f 显示文件全路径ls -R也可以显示树结构,但没上面 清晰 3.tree -L n n 是数字,表示显示几层 4 ...
- 今日资源帖-PPT逆袭秘籍72集+2000套模板,太经典了
好资源不私藏,分享是一种态度 今日给大家分享的是PPT教程和2000套模板 如何让PPT成为你职场的利器 如何让你的PPT更具表现力 2000套模板随便选 PPT视频教程 链接 https://pan ...
- 使用python执行系统命令——subprocess
背景:subprocess是python官方推荐调用系统命令的模块 import subprocess subprocess最主要的两个方法/类: # 参数说明:stdin和stdout相当于一个管 ...
- ETCD:运行时重新配置设计
原文地址:the runtime configuration design 运行时重新配置是分布式系统中最难,最容易出错的部分,尤其是在基于共识(像etcd)的系统中. 阅读并学习关于etcd的运行时 ...