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 循环的数据类型有以下两种:

  1. 一类是集合数据类型,如 list、tuple、dict、set、str 等
  2. 一类是 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)的更多相关文章

  1. python生成器(generator)、迭代器(iterator)、可迭代对象(iterable)区别

    三者联系 迭代器(iterator)是一个更抽象的概念,任何对象,如果它的类有next方法(next python3)和__iter__方法返回自己本身,即为迭代器 通常生成器是通过调用一个或多个yi ...

  2. 【python之路29】python生成器generator与迭代器

    一.python生成器 python生成器原理: 只要函数中存在yield,则函数就变为生成器函数 #!usr/bin/env python # -*- coding:utf-8 -*- def xr ...

  3. python 生成器和迭代器有这篇就够了

    本节主要记录一下列表生成式,生成器和迭代器的知识点 列表生成器 首先举个例子 现在有个需求,看列表 [0,1,2,3,4,5,6,7,8,9],要求你把列表里面的每个值加1,你怎么实现呢? 方法一(简 ...

  4. Python学习笔记 - 迭代器Iterator

    我们已经知道,可以直接作用于for循环的数据类型有以下几种: 一类是集合数据类型,如list.tuple.dict.set.str等: 一类是generator,包括生成器和带yield的genera ...

  5. Python生成器,迭代器,可迭代对象

    在了解Python的数据结构时,容器(container).可迭代对象(iterable).迭代器(iterator).生成器(generator).列表/集合/字典推导式(list,set,dict ...

  6. python 生成器和迭代器介绍

    在正式接触生成器之前,我们先来了解一些概念 容器(container) 容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个迭代获取,可以用in.not in关键字判断元素是否包含在容器中. ...

  7. 【转】python 生成器和迭代器有这篇就够了

    总结得特别好,转自:https://www.cnblogs.com/wj-1314/p/8490822.html 本节主要记录一下列表生成式,生成器和迭代器的知识点 列表生成器 首先举个例子 现在有个 ...

  8. python生成器、迭代器、__call__、闭包简单说明

    1.生成器 这种一边循环一边计算的机制,称为生成器:generator,最简单的方法是把生成式的[]改为(). >>> l=(x * x for x in range(1, 11) ...

  9. Python 生成器与迭代器 yield 案例分析

    前几天刚开始看 Python ,后因为项目突然到来,导致Python的学习搁置了几天.然后今天看回Python 发现 Yield 这个忽然想不起是干嘛用的了(所以,好记性不如烂笔头.).然后只能 花点 ...

随机推荐

  1. 红黑树原理详解及golang实现

    目录 红黑树原理详解及golang实现 二叉查找树 性质 红黑树 性质 operation 红黑树的插入 golang实现 类型定义 leftRotate RightRotate Item Inter ...

  2. Java EE 基本开发流程及数据库连接池 Druid

    一. 公司开发基本流程    a. 了解需求信息(比较模糊)        需求,不是别人告诉你的,是你自己挖掘出来的.        售前工程师(对行业知识了解):编程学不好,但懂点代码,对人的综合 ...

  3. eCharts二三维地图总结

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 最近多个项目中的登录页面陆续提出了不少地图需求,主要围绕地图的 ...

  4. html5的 history模式和hash模式

    直观区别 hash 带一个# history 没有# 各自特点 hash: 仅 hash 符号之前的内容会被包含在请求中,**因此对于后端来说,即使没有做到对路由的全覆盖,也不会返回 404 错误.* ...

  5. SharePoint 2019 里安装FlowPortal6.00c报错

    环境: Windows Server 2016+SharePoint 2019 安装FlowPortal 6.00c后应用程序池FlowPortal.net 6.x AppPool自动停止. 事件查看 ...

  6. [20191125]探究等待事件的本源.txt

    [20191125]探究等待事件的本源.txt --//当工作中遇到oracle的性能问题时,查看awr报表提供很好的解决问题途径.但是有时候很容易想当然.--//比如以前我一看到 log file ...

  7. Step by Step Process of Migrating non-CDBs and PDBs Using ASM for File Storage (Doc ID 1576755.1)

    Step by Step Process of Migrating non-CDBs and PDBs Using ASM for File Storage (Doc ID 1576755.1) AP ...

  8. 连接 sql

    java连接sqlserver 1 创建 Dynamic Web Project项目 在WebContent/WEB-INF/lib中添加sqljdbc42.jar 2 在class文件里连接数据库 ...

  9. ubuntu 安装谷歌浏览器

    如何在ubuntu 中安装谷歌浏览器, 对于一个刚刚接触ubuntu的人来说,希望安装软件更加的简单,明了.最好能够像在windows下面安装软件一样. 先来介绍一下如何快速的安装谷歌浏览器,以下的方 ...

  10. nginx如何实现负载均衡以及实现方式

    什么是ngnix? Nginx是一个http服务器.是一个使用c语言开发的高性能的http 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器.nginx能够支撑5万并发链接,并且cpu ...