彻底搞懂python 迭代器和生成器


Posted in Python onSeptember 07, 2020

迭代器跟生成器,与上篇文章讲的装饰器一样,都是属于我的一个老大难问题。
通常就是遇到的时候就去搜一下,结果在一大坨各种介绍博客中看了看,回头又忘记了。
你是不是也是这样呢?

俗话说:好记性不如烂笔头,虽然现在基本不咋用笔写字了,但是还是要好好整理下,起码以后我就不用搜了。

如果现在给你一个列表list_a = [1, 2, 3, 4],让你去迭代它,相信大家都很熟悉,直接用for循环就完事儿,

list_a = [1, 2, 3, 4]

for i in list_a:
 print(i)

运行

1
2
3
4
[Finished in 0.1s]

可以看到,for循环迭代了列表中的每一个元素,打印了出来。
那么for循环背后都做了什么事情呢?

一、 容器、可迭代对象、迭代器

听起来陌生,但是你绝对熟悉的词儿。

在python中,一切都是对象,对象的抽象是类,而对象的集合就是容器。

使用python中常见的容器有很多,比如:列表list:[0, 1, 2],集合set:([0, 1, 2]),字典dict:{0:0, 1:1, 2:2}以及元组tuple(0, 1, 2)
这些都是多个元素集中在一起的单元,区别的是内部数据结构的实现方法。

所有的容器都是可以迭代的,你可以用for循环去迭代上述的容器试试。

那把一个个元素找出来,用到的就是迭代器。用iter()可以创建一个迭代器。

迭代器提供一个next()方法,这个方法你每次调用的时候会给你返回下一个对象,或者StopIteration,也就是没有对象可以给你了。

list_a = [1, 2, 3, 4]

it = iter(list_a) # 创建迭代器

print(next(it)) #调用next()
print(next(it))
print(next(it))
print(next(it))
print(next(it))

运行结果,前4个print可以正常返回,第5个时候就出现StopIteration错误了,因为列表中4个元素已经返回完了。

1
2
3
4
Traceback (most recent call last):
File "D:\练习\demo_iterator.py", line 9, in <module>
print(next(it))
StopIteration
[Finished in 0.1s with exit code 1]

二、生成器

什么是生成器?简单粗暴一点:生成器就是懒人版的迭代器。

在上述的创建迭代器操作中,我们显然是做了一次性生成的操作,list_a = [1, 2, 3, 4],这4个元素一次性生成好,以供next()调用。

但是生成出的这些元素都是会保存到内存中去,这只是4个元素,如果有上千万、上亿元素呢?
我并不是第一时间要用到所有的元素,我只要在我调用next()的时候产生一个返回给我就好,那么这样一次性生成就会白白占用了大量的内存。

生成器应运而生,当调用next()的时候,才会生成下一个变量。
生成器的写法很简单,用小括号,比如把一个列表生成式括起来:(i for i in range(10000))这样就初始化了一个生成器。

print([i for i in range(10)])

print(i for i in range(10))

上面的时列表,下面的就是一个生成器了,区别就是[]和()。
运行结果:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
<generator object <genexpr> at 0x033383A8>
[Finished in 0.1s]

yield关键字

此外,函数也可以成为生成器,秘密就是yield关键字,比如:

def gen():
 a = 0
 while a < 100:
  yield a
  a += 1

test = gen()
print(next(test))
print(next(test))
print(next(test))
print(next(test))

运行结果:

0
1
2
3
[Finished in 0.1s]

yield关键字,可以这样理解:当函数运行到这一行的时候,程序会从这里暂停,yield相当于return会返回,
当下次迭代时候,则会从yield的下一行代码开始执行。

所以,我调用了4次print,可以从0开始依次输出。

从我工作中的使用场景出发的话,我在做一些自动化测试的时候,有些变量参数是不可以重复的,用迭代器来定义变量的生成规则,每次
调用都会产生一个新的,就不会重复了。

以上就是彻底搞懂python 迭代器和生成器的详细内容,更多关于python 迭代器和生成器的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python变量和字符串详解
Apr 29 Python
python实现媒体播放器功能
Feb 11 Python
Python cookbook(数据结构与算法)在字典中将键映射到多个值上的方法
Feb 18 Python
Flask核心机制之上下文源码剖析
Dec 25 Python
python去重,一个由dict组成的list的去重示例
Jan 21 Python
解决Python3用PIL的ImageFont输出中文乱码的问题
Aug 22 Python
python GUI库图形界面开发之PyQt5 UI主线程与耗时线程分离详细方法实例
Feb 26 Python
在jupyter notebook中调用.ipynb文件方式
Apr 14 Python
python实现扑克牌交互式界面发牌程序
Apr 22 Python
通过实例解析python subprocess模块原理及用法
Oct 10 Python
Python利用matplotlib绘制折线图的新手教程
Nov 05 Python
关于的python五子棋的算法
May 02 Python
python如何设置静态变量
Sep 07 #Python
获取CSDN文章内容并转换为markdown文本的python
Sep 06 #Python
浅谈Python描述数据结构之KMP篇
Sep 06 #Python
详解Python3 定义一个跨越多行的字符串的多种方法
Sep 06 #Python
Python中实现一行拆多行和多行并一行的示例代码
Sep 06 #Python
Pytest单元测试框架如何实现参数化
Sep 05 #Python
Python实例方法、类方法、静态方法区别详解
Sep 05 #Python
You might like
解析crontab php自动运行的方法
2013/06/24 PHP
深入理解PHP中mt_rand()随机数的安全
2017/10/12 PHP
php利用云片网实现短信验证码功能的示例代码
2017/11/18 PHP
Laravel 实现在Blade模版中使用全局变量代替路径的例子
2019/10/22 PHP
PHP使用PhpSpreadsheet操作Excel实例详解
2020/03/26 PHP
传递参数的标准方法(jQuery.ajax)
2008/11/19 Javascript
ExtJs3.0中Store添加 baseParams 的Bug
2010/03/10 Javascript
js中将字符串转换成json的三种方式
2011/01/12 Javascript
纯javascript移动优先的幻灯片效果
2015/11/02 Javascript
JS与jQuery遍历Table所有单元格内容的方法
2015/12/07 Javascript
WordPress 单页面上一页下一页的实现方法【附代码】
2016/03/10 Javascript
纯JavaScript手写图片轮播代码
2016/10/20 Javascript
js return返回多个值,通过对象的属性访问方法
2017/02/21 Javascript
vue2.0实现倒计时的插件(时间戳 刷新 跳转 都不影响)
2017/03/30 Javascript
深入理解vue.js中$watch的oldvalue与newValue
2017/08/07 Javascript
js实现前面自动补全位数的方法
2018/10/10 Javascript
详解在不使用ssr的情况下解决Vue单页面SEO问题
2018/11/08 Javascript
javascript实现视频弹幕效果(两个版本)
2019/11/28 Javascript
jquery实现有过渡效果的tab切换
2020/07/17 jQuery
[01:23:45]DOTA2-DPC中国联赛 正赛 CDEC vs Dragon BO3 第一场 1月22日
2021/03/11 DOTA
python缩进区别分析
2014/02/15 Python
python实现数通设备tftp备份配置文件示例
2014/04/02 Python
python使用chardet判断字符串编码的方法
2015/03/13 Python
详解JavaScript编程中的window与window.screen对象
2015/10/26 Python
Python hashlib模块用法实例分析
2018/06/12 Python
对python多线程中互斥锁Threading.Lock的简单应用详解
2019/01/11 Python
Django中reverse反转并且传递参数的方法
2019/08/06 Python
python redis 批量设置过期key过程解析
2019/11/26 Python
python自定义函数def的应用详解
2020/06/03 Python
python 如何上传包到pypi
2020/12/24 Python
加拿大领先家居家具网上购物:Aosom.ca
2020/05/27 全球购物
青年创业培训欢迎词
2014/01/08 职场文书
《鹬蚌相争》教学反思
2014/04/22 职场文书
2015年度信用社工作总结
2015/05/04 职场文书
上课迟到检讨书范文
2015/05/06 职场文书
MySQL不使用order by实现排名的三种思路总结
2021/06/02 MySQL