Python3迭代器和生成器

很多朋友在初次接触 python 的 迭代器 和 生成器 时,总是不理解 生成器 和 迭代器的作用 和它们之间的关系,今天笔者来详细的讲解一下。


知识点目录:

一、迭代器

1.什么是迭代器

2.举例说明

3.StopIteration 异常的作用

4.举例说明 StopIteration 的作用

二、生成器

1.什么是生成器

2.生成器的优点

3.创建生成器的方式

4.生成器的两种方法

三、生成器 和 迭代器 的区别


一、迭代器

1.什么是迭代器

迭代是访问集合元素的一种方式,迭代器是一种可以记住遍历位置的对象。迭代器只能往前不能后退。

迭代器是可以被 next()函数调用并返回下一个值的对象

迭代器中,重点关注两种方法:

__iter__ 方法:返回一个迭代器对象,可以通过 python 内建函数 iter()调用。这个迭代器对象实现了 __next__ 方法,并通过 StopIteration 异常来标识迭代的完成。

__next__ 方法:返回下一个迭代器对象,可以通过 python 内建函数 next()调用。


2.举例说明

# 元组可迭代数据类型
i = iter((1,2,3))    # 调用 iter()方法,获得迭代器对象print(type(i))    # 打印数据类型
print(next(i))
print(next(i))    # 调用 next()方法,获得下一个迭代器对象
print(next(i))
print(next(i))# 结果
<class 'tuple_iterator'>
1
2
3# 异常:
Traceback (most recent call last):File "D:/Pycharm Perject save path/python/CeShi.py", line 19, in <module>print(next(i))
StopIteration# 异常原因:
元组内的元素一共是 3 个,而我调用了 4 次 next()方法,每次都会返回一个元素,
当没有元素可以返回的时候,就会自动抛出异常 StopIteration 。一般情况下,我们使用 for 循环来遍历 数据,这样可以避免因为异常而停止程序运行。

3.StopIteration 异常的作用

StopIteration 异常 用来标记迭代的完成,防止出现无限循环的情况。当重写 迭代器类 时,我们可以在 __next__() 方法中设置当完成指定循环次数后,触发 StopIteration 异常来结束迭代。

4.举例说明 StopIteration 异常的作用

# 举例说明 StopIteration 的作用
class MyNumbers:def __iter__(self):self.a = 1return selfdef __next__(self):if self.a <= 4:x = self.aself.a += 1return xelse:raise StopIteration    # raise 语句来触发一个异常(抛出异常)myclass = MyNumbers()
myiter = iter(myclass)for x in myiter:print(x)# 结果
1
2
3
4

二、生成器

1.什么是生成器

在 python 中,使用了 yield 关键字的函数被称为 生成器(generator)。

和普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单的理解 生成器就是一个迭代器。

在调用生成器运行的过程中,每次遇到yield关键字 函数都会暂停运行并保存当前的所有运行信息,然后返回 yield关键字 的值,并在下一次执行 next()方法时从当前位置继续执行。

调用一个生成器,返回的是一个迭代器对象。


2.生成器的优点

1.节约内存,python 在使用生成器时对延迟操作提供了支持。所谓延迟,是指在需要的时候才产生结果,而不是立即产生结果。比如在大数据中,会使用生成器来调取数据结果而不是列表来处理数据,因为使用生成器可以 节省内存

2.迭代到下一次的调用时,所使用的参数都是第一次所保留的。

3.创建生成器的方式

1.生成器表达式

类似于 列表推导式,将列表推导式的中括号,替换成圆括号,就是一个生成器表达式,但是生成器每次返回的结果只有一个,而不是一次构建一整个结果列表。

例子:

# 列表推导式
data = [i ** 2 for i in range(5)]
print(type(data))
print(data)# 结果
<class 'list'>
[0, 1, 4, 9, 16]# 生成器表达式
data = (i ** 2 for i in range(5))
print(type(data))for i in data:    # 使用for循环遍历 data print(i)# print(type(data))
# print(next(data))
# print(next(data))
# print(next(data))
# print(next(data))
# print(next(data))
# print(next(data))    # 获取第6次抛出 StopIteration 异常,使用 for 循环即可。# 结果
<class 'generator'>
0
1
4
9
16

2.生成器函数

生成器函数 和 常规函数定义差不多,但是使用 yield关键字 来返回结果,而不是 return。yield 关键字每次会返回一个结果,然后将程序的运行状态挂起,以便下一次从它离开的地方继续执行。

例子:

# 生成器函数
def odd():n = 1while True:yield nn += 2odd_num = odd()  # 调用生成器函数
count = 0
for o in odd_num:  # 从生成器函数中,遍历循环数据if count >= 5:breakprint(o)  # 打印遍历出来的数据count += 1# 结果
1
3
5
7
9

上面的生成器函数的例子中,关键字 yield 是必备的。当一个普通函数中包含 yield 关键字时,系统会默认为是一个 generator(生成器)。


4.生成器的两种方法

生成器的两种方法 __next__() 和 send()方法。

__next__()方法 和 next()方法的作用是一样的。

send()方法向生成器函数中传入数据

4.1 __next__()方法

# next() 方法示例
def odd():n=1while True:yield nn+=2
odd_num=odd()for i in range(4):print(next(odd_num))# __next__() 方法示例
def odd():n=1while True:yield nn+=2
odd_num=odd()for i in range(4):print(odd_num.__next__())# 结果
1
3
5
7
1
3
5
7

从上面的程序中可以看出,next(odd_num)  和  odd_num.__next__() 的作用是一样的。

4.2 send()

# send()方法示例
def fib(times):n = 0a, b = 0, 1while n < times:temp = yield b  # 在 yield 前面添加一个变量print(temp)a, b = b, a + bn += 1f = fib(5)
print(f.__next__()) # 调用 __next__ 打印值
print(f.send("Super Man 超人"))   # 使用send()方法传入值
print(f.send("lron Man 钢铁侠"))# 结果
1
Super Man 超人
1
lron Man 钢铁侠
2

从上面的示例中可以看到,使用 send()方法时,必须在 yield 关键字前面添加一个变量,并打印这个变量。但是强调一点,在使用send()方法之前,必须要先使用至少一次 __next__ 方法,因为生成器不可以在使用之前导入任何非None的参数。由此可以知道,send()是用来向生成器中导入参数并返回该参数的,与该参数一起返回的还有生成器中原先保存的数据。


三、生成器 和 迭代器 的区别

生成器能够做到迭代器能做的所有事情,而且因为生成器自动创建了 iter()和 next()方法,所以会显得更加简洁一些,同时生成器相对更加高效,使用 生成器 表达式 取代 列表解析 可以节省内存。除了 创建 和 保存程序状态 的自动方法,当没有 yield 可以返回的值时,自动抛出 StopIteration 异常。


非常感谢同仁的观看.如果小编写的有问题,欢迎评论.发现问题后会第一时间修改.

祝大家工作学习顺利.    ♥(ˆ◡ˆԅ)

python生成器和迭代器相关推荐

  1. python生成器和迭代器作用_浅谈Python中的生成器和迭代器

    迭代器 迭代器协议 对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么返回一个异常来终止本次迭代.(只能往前走,不能往后退!) 迭代器对象 遵循了(实现了)迭代器协议的对象.(对象内 ...

  2. Python生成器与迭代器

    Python生成器与迭代器 前言 首先,来让我们弄清楚可迭代对象 可迭代对象 在python中,可迭代对象并不是指某种具体的数据类型,它是指存储了元素的一个容器对象 也就是说,如果容器里面没有存储数据 ...

  3. 详解 Python 生成器与迭代器 及其区别

    前言 不论是初学python还是python进阶,这都是绕不开的知识点,生成器与迭代器的概念相较于其他基础概念显得晦涩难懂,知识点囊括很多方面,查阅越多的资料,头就越大,现在这加以理解归纳总结. 相关 ...

  4. Python生成器、迭代器

    Python生成器.迭代器 一.生成器(generator) 通过列表生成式,我们可以直接创建一个列表.但是,受到内存限制,列表容量肯定是有限的.而且,创建一个包含100万个元素的列表,不仅占用很大的 ...

  5. 彻底理解Python生成器和迭代器

    目录 1.列表生成式 2.生成器 3.迭代器 4.对yield的总结 5.补充:itertools库学习 1.列表生成式 首先举个例子 现在有个需求,看列表 [0,1,2,3,4,5,6,7,8,9] ...

  6. Python生成器与迭代器详细教程

    一.列表生成器 首先举个例子 现在有个需求,看列表 [0,1,2,3,4,5,6,7,8,9],要求你把列表里面的每个值加1,你怎么实现呢? 方法一(简单): info = [0, 1, 2, 3, ...

  7. 没有5年测开经验,还真说不清Python生成器、迭代器、装饰器

    一.什么是生成器? 使用了yield函数 就被称之为生成器,生成器是一个返回迭代器的函数,说白了生成器就是迭代器,只能用于迭代操作. 不懂?没关系,下面就一个斐波那契数列为例来进行讲解: 依靠简单循环 ...

  8. python生成器与迭代器(配套相关案列解析用法)

    一.python生成器简介 在 Python 中,使用了 yield 的函数被称为生成器(generator).跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就 ...

  9. python生成器和迭代器详解

    文章目录 前言 一.迭代器--从一个简单例子入手 1.1 实现__iter__成为迭代对象 1.2 通过实现__next__方法成为迭代器 二.生成器 -- 更加简单的迭代器 2.1来个简单例子 2. ...

最新文章

  1. MFC通过ODBC连接mysql(使用VS2012编写MFC)
  2. 201521123054《Java程序设计》第1周学习总结
  3. frida hook so层方法大全
  4. Delphi开发环境中应用层网络协议的实现
  5. C# 10 完整特性介绍
  6. 实例7:python
  7. NLP《词汇表示方法(七)BERT》
  8. python天气数据分析可视化_python可视化爬虫界面之天气查询
  9. 如何将一个完整项目推到码云_怎么将本地项目放到码云(gitee)上面?图文详解
  10. 如何根据自己需要截取字符串
  11. 调用wsdl的接口-用axis
  12. java山地车 故障,十年骑龄车友总结山地车保养维修技巧
  13. 无线测温采集设备及无线测温监控系统的选型指导-安科瑞王婧
  14. 新开发的微信小程序怎样推广引流?
  15. [重磅]秦雯讲大数据:心动.幡动.风动
  16. 邀你来看 | CSDN公开课 利用容器技术打造AI公司技术中台
  17. K8S Flannel
  18. 硬盘分区显示空间大小比实际值小的解决办法,如何给硬盘精确分区
  19. 对抗机器学习——FGSM经典论文 EXPLAINING AND HARNESSING ADVERSARIAL EXAMPLES
  20. 华师大 OJ 3026

热门文章

  1. 用OneNote打造全平台的数字笔记本
  2. 单片机彩灯移动实验_51单片机键控彩灯实验
  3. 大数据说:原来“首堵”不是北京!
  4. 笔记本电脑win10系统,麦克风突然没声音了
  5. 人工智能洗衣机模糊推理系统实验(课本实验)
  6. 北师大版图形的旋转二教案_北师大版数学六年级下册《图形的旋转(二)》教案疲惫不堪的意思...
  7. python 电梯运行_面向对象电梯系列总结
  8. 深圳云计算培训学习:如何评价我国云计算的发展现状?--【千锋】
  9. 大小写数字转换(大小写数字转换)
  10. 【1059】求平均年龄