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. 更换国内pip

    pip国内的一些镜像 原始地址:https://pypi.python.org/simple 国内地址: 阿里云 http://mirrors.aliyun.com/pypi/simple/ 中国科技 ...

  2. Centos下使用yum命令报错 except KeyboardInterrupt, e: SyntaxError: invalid syntax

    使用yum命令报错 File "/usr/bin/yum", line 30 except KeyboardInterrupt, e: ^ SyntaxError: invalid ...

  3. Axure导出的原型无法在谷歌浏览器浏览

    1.下载crx后缀的文件. 2.修改crx后缀名为rar的压缩文件 3.解压刚才的rar文件 4.打开谷歌浏览器右上角的三个点 更多工具==>扩展程序 选择刚才的解压文件夹. 上面的图表示安装成 ...

  4. html5的 history模式和hash模式

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

  5. Rsync实现文件的同步

    故事背景:我们公司是做新零售的,需要对发布的每台机器进行文件的同步更新,所以我这里做了一个小小的调研 技术调研:linux之间同步文件有两种方式rsync与scp. sync和scp在文件夹均不存在时 ...

  6. 49-在 overlay 中运行容器

    上一节我们创建了 overlay 网络 ov_net1,今天将运行一个 busybox 容器并连接到 ov_net1: 查看容器的网络配置: bbox1 有两个网络接口 eth0 和 eth1.eth ...

  7. JavaScript-----13.内置对象 Math()和Date()

    1. 内置对象 js对象分为3种:自定义对象(var obj={}).内置对象.浏览器对象. 前两种对象是js基础内容,属于ECMAScript,第三个浏览器对象是js独有的.讲js API的时候会讲 ...

  8. 3万字长文概述:通俗易懂告诉你什么是.NET?什么是.NET Framework?什么是.NET Core?

    [转载]通俗易懂,什么是.NET?什么是.NET Framework?什么是.NET Core? 什么是.NET?什么是.NET Framework?本文将从上往下,循序渐进的介绍一系列相关.NET的 ...

  9. [译]Vulkan教程(10)交换链

    [译]Vulkan教程(10)交换链 Vulkan does not have the concept of a "default framebuffer", hence it r ...

  10. angularjs中directive指令与component组件有什么区别?

     壹 ❀ 引 我在前面花了两篇博客分别系统化介绍了angularjs中的directive指令与component组件,当然directive也能实现组件这点毋庸置疑.在了解完两者后,即便我们知道co ...