Python学习之迭代器详解


Posted in Python onApril 01, 2022

什么是迭代器

迭代是 python 中访问集合元素的一种非常强大的一种方式。迭代器是一个可以记住遍历位置的对象,因此不会像列表那样一次性全部生成,而是可以等到用的时候才生成,因此节省了大量的内存资源。迭代器对象从集合中的第一个元素开始访问,直到所有的元素被访问完。迭代器有两个方法:iter()和 next()方法。

这么解释可能不太直观,我们以生活的一个小栗子来解释一下,方便大家能够更深刻的理解。比如说我们去超市买水果,而正巧超市的服务人员正在摆放苹果。服务人员告诉我们需要等苹果都摆放完毕我们才可以拿苹果,这样就很耽误我们的时间。(这个场景中,柜台上其实已经有苹果了,只不过销售不让拿罢了。)

然后我们再去卖橘子的柜台,服务人员也在摆放橘子。但是服务人员告诉我们可以不用等他摆放完毕,我们可以直接拿橘子,这样就会很好的节省我们的时间。如果我们拿橘子的速度超过了服务人员摆放的速度 ,我们只需要等待服务人员摆放之后就可以直接拿橘子,大大的提升了我们买橘子的效率。

而迭代器就类似于我们买橘子的场景,我们平时的程序都是一次性写入到内存中。比如我们的列表中存在成百上千的数据,都是一次性写入到内存里的,通过这样让我们来使用。但是迭代器却是按需加载,有一点内容就会放在内容里面,我们就可以立刻使用内存中的数据进行我们的逻辑处理。这样就不要所有的数据都写入到内存中就可以使用,大大的提升了使用效率。

如何生成迭代器

迭代器函数 - iter() 函数 与 next() 函数

iter(iterable)从可迭代对象中返回一个迭代器,iterable必须是能提供一个迭代器的对象

next(iterator) 从迭代器iterator中获取下一了记录,如果无法获取下一条记录,则触发stoptrerator异常
说明:

1.迭代器只能往前取值,不会后退

2.用iter函数可以返回一个可迭代对象的迭代器

示例:

iter()函数介绍:生成一个迭代器对象

iter()函数用法:iter(iterable)

参数介绍:iterable —> 可迭代的数据类型(比如列表、字典、元组以及集合类型等)

示例:

iter([1, 2, 3])

返回值:

<list_iterator at 0x4f3bff0>

next()函数介绍:返回迭代器中的数据

next()函数用法:next(iterable)

参数介绍:iterable —> 迭代器对象

示例:

iter_obj = iter([1,2,3])
next(iter_obj)

返回值:

# >>> 1,2,3
# >>> StopIteration

综上,我们得出结论:

iter(iterable)从可迭代对象中返回一个迭代器,iterable必须是能提供一个迭代器的对象

next(iterable) 从迭代器iterator中获取下一了记录,如果无法获取下一条记录,则触发stoptrerator异常

演示案例如下:

# coding:utf-8


test_list = [1, 3, 5, 7]
test_iter = iter(test_list)     # 让test_list提供一个能访问自己的迭代器
print(next(test_iter))     # 1  从迭代器中取值,让迭代器去获取l中的一个元素
print(next(test_iter))     # 3
print(next(test_iter))     # 5
print(next(test_iter))     # 7
print(next(test_iter))     # StopIterable 异常

test_list 实际上是一个列表,但是被迭代器迭代之后。并不是一次性将列表放入内存中,而是每次放一个元素进入内存,然后被读取。(这就是我们说的按需加载)

Python学习之迭代器详解

可迭代的对象

类似于list、tuple、str 等类型的数据可以使用for… in… 的循环遍历语法可以从其中依次拿到数据并进行使用,我们把这个过程称为遍历,也称迭代。python中可迭代的对象有list(列表)、tuple(元组)、dirt(字典)、str(字符串)set(集合)等。

示例如下:

test_list = [1,2,3,4,5]
test_dirt = {
    "name":"张三",
    "sex":"男",
    "age":33
    }
    
test_tuple = (1,2,3,4,5)
test_set = {1,2,3,3,4}
 
    
for i in test_list:
    print(i)
 
for i in test_dirt:
    print(i)
 
for i in test_tuple:
    print(i)
 
for i,j in test_set.items():
    print("%s:%s" % (i,j))
    
# >>> 执行结果如下:
# >>> test_list的元素为: 1
# >>> test_list的元素为: 2
# >>> test_list的元素为: 3
# >>> test_list的元素为: 4
# >>> test_list的元素为: 5
# >>> test_dirt的元素为: name
# >>> test_dirt的元素为: sex
# >>> test_dirt的元素为: age
# >>> test_tuple的元素为: 1
# >>> test_tuple的元素为: 2
# >>> test_tuple的元素为: 3
# >>> test_tuple的元素为: 4
# >>> test_tuple的元素为: 5
# >>> test_set的元素为:1
# >>> test_set的元素为:2
# >>> test_set的元素为:3
# >>> test_set的元素为:4

生成迭代器

除了刚刚我们使用的 iter() 函数之外 ,我们还有其他方法生成迭代器:

第一种:for循环生成方法 —> 我们可以在函数中使用 for 循环, 并对每一个 for 循环的成员使用 yield() 函数 [它的意思就是将每一个 for 循环成员放到一个迭代器对象中,不过只有被调用才会被放入。]

示例如下:

def test():
    for i in range(10):
        yield i


result = test()

print('for 循环,第一次 \'i\'的值为:', next(result))
print('for 循环,第二次 \'i\'的值为:', next(result))
print('for 循环,第三次 \'i\'的值为:', next(result))
print('for 循环,第四次 \'i\'的值为:', next(result))

# >>> 执行结果如下:
# >>> for 循环,第一次 'i'的值为: 0
# >>> for 循环,第二次 'i'的值为: 1
# >>> for 循环,第三次 'i'的值为: 2
# >>> for 循环,第四次 'i'的值为: 3

Python学习之迭代器详解

注意:超过10次异常会抛 StopIteration 的异常。

第二种:for 循环一行生成迭代器对象。

示例如下:

result = (i for i in [1, 2, 3])        # 将 for 循环在非函数中 赋值 给一个变量, 这也是生成一个迭代器变量的方法  

print('for 循环,第一次 \'i\'的值为:', next(result))        # 使用 next 调用迭代器
print('for 循环,第二次 \'i\'的值为:', next(result))
print('for 循环,第三次 \'i\'的值为:', next(result))

# >>> for 循环,第一次 'i'的值为: 1
# >>> for 循环,第二次 'i'的值为: 2
# >>> for 循环,第三次 'i'的值为: 3

Python学习之迭代器详解

注意: next(result) 超过4次会抛 StopIteration 的异常。

划重点:

使用 for 循环生成的迭代器,可以不使用 next() 函数 也可以执行,(依然可以通过 for 循环 获取迭代器的数据)不仅如此,当我们调取完迭代器中的数据之后,程序不会抛出异常,相比较与 next() 函数要友好的多。

示例如下:

result = (i for i in [1, 2, 3])

for item in result:
    print(item)
    
# >>> 执行结果如下:
# >>> 1
# >>> 2
# >>> 3

# 循环结束,程序正常退出,不会抛出 StopIteration 的异常

迭代器的用法 - 演示案例

案例一:

def make_iter():
    for i in range(5):
        yield i

iter_obj = make_iter()

for i in iter_obj:
    print(i)
print('----')
for i in iter_obj:
    print(i)
    
# >>> 执行结果如下:
# >>> 0
# >>> 1
# >>> 2
# >>> 3
# >>> 4
# >>> ----

# >>> 从运行结果得出结论,当我们从内存中读取完迭代器所有的值后,内存就会被释放,不再循环输出。

案例二:

iter_obj = (i for i in range(4))

for i in iter_obj:
    print(i)
print('=====')
for i in iter_obj:
    print(i)

# >>> 执行结果如下:
# >>> 0
# >>> 1
# >>> 2
# >>> 3
# >>> =====
# >>> 从运行结果得出结论,当我们从内存中读取完迭代器所有的值后,内存就会被释放,不再循环输出。

迭代器 除了前文我们提到的 按需加载 ,可以提升我们的执行速度以外。

还有另外一个原因,试想一下:如果我们的列表只有10个数据,那么读取的速度会很快。可能对资源(也就是我们的内存)占用的消耗不是很大;如果我们有一个成千上万甚至十万数据的列表,那么这些数据都要一次性的写入内存里,这么多的数据所消耗占用的资源必然会很大,甚至会撑爆我们的内存造成内存溢出,程序就会报错了。

所以如果通过迭代器的方式,我们只需要用到一个数据就将一个数据扔到内存里并且被使用。这样既可以提高我们内存使用的效率,又可以减少我们内存的消耗。这也是我们平时使用迭代器的目的。

到此这篇关于Python学习之迭代器详解的文章就介绍到这了,更多相关Python迭代器内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python使用socket连接远程服务器的方法
Apr 29 Python
解决Python 遍历字典时删除元素报异常的问题
Sep 11 Python
python基本语法练习实例
Sep 19 Python
python matplotlib坐标轴设置的方法
Dec 05 Python
python操作xlsx文件的包openpyxl实例
May 03 Python
wxPython的安装与使用教程
Aug 31 Python
python实现zabbix发送短信脚本
Sep 17 Python
在python带权重的列表中随机取值的方法
Jan 23 Python
Python3.5内置模块之time与datetime模块用法实例分析
Apr 27 Python
python按照list中字典的某key去重的示例代码
Oct 13 Python
Python3+Django get/post请求实现教程详解
Feb 16 Python
Pygame Draw绘图函数的具体使用
Nov 17 Python
Python实战之大鱼吃小鱼游戏的实现
OpenCV实现常见的四种图像几何变换
关于Python使用turtle库画任意图的问题
Apr 01 #Python
python套接字socket通信
python文件与路径操作神器 pathlib
Python下载商品数据并连接数据库且保存数据
Python turtle编写简单的球类小游戏
You might like
PHP设计模式 注册表模式
2012/02/05 PHP
php遍历目录输出目录及其下的所有文件示例
2014/01/27 PHP
Codeigniter上传图片出现“You did not select a file to upload”错误解决办法
2014/06/12 PHP
PHP SESSION机制的理解与实例
2019/03/22 PHP
如何做到打开一个页面,过几分钟自动转到另一页面
2007/04/20 Javascript
javascript实现动态CSS换肤技术的脚本
2007/06/29 Javascript
Javascript 原型和继承(Prototypes and Inheritance)
2009/04/01 Javascript
jQuery 创建Dom元素
2010/05/07 Javascript
jQuery中live方法的重复绑定说明
2011/10/21 Javascript
jQuery下通过replace字符串替换实现大小图片切换
2012/05/22 Javascript
js函数调用常用方法详解
2012/12/03 Javascript
js获取或设置当前窗口url参数的小例子
2013/10/14 Javascript
使用变量动态设置js的属性名
2014/10/19 Javascript
js style动态设置table高度
2014/10/21 Javascript
javascript动态创建及删除元素的方法
2014/12/22 Javascript
JavaScript调试工具汇总
2014/12/23 Javascript
JavaScript 常见安全漏洞和自动化检测技术
2015/08/21 Javascript
详解AngularJS中module模块的导入导出
2015/12/10 Javascript
jQuery实现点击行选中或取消CheckBox的方法
2016/08/01 Javascript
使用伪命名空间封装保护独自创建的对象方法
2016/08/04 Javascript
vue.js配合$.post从后台获取数据简单demo分享
2018/08/11 Javascript
JavaScript实现随机点名器实例详解
2019/05/07 Javascript
layui实现图片虚拟路径上传,预览和删除的例子
2019/09/25 Javascript
[01:34]2014DOTA2展望TI 剑指西雅图VG战队专访
2014/06/30 DOTA
Python实现115网盘自动下载的方法
2014/09/30 Python
Python实现正弦信号的时域波形和频谱图示例【基于matplotlib】
2018/05/04 Python
详解python 注释、变量、类型
2018/08/10 Python
详解Python打包分发工具setuptools
2019/08/05 Python
python opencv图片编码为h264文件的实例
2019/12/12 Python
css3 border-radius属性详解
2017/07/05 HTML / CSS
使用HTML5的File实现base64和图片的互转
2013/08/01 HTML / CSS
小学生保护环境倡议书
2014/05/15 职场文书
学校群众路线专项整治方案
2014/10/31 职场文书
工作经验交流材料
2014/12/30 职场文书
公司借款担保书
2015/09/22 职场文书
创业计划书之服装
2019/10/07 职场文书