Python学习之迭代器详解
作者:渴望力量的哈士奇 发布时间:2022-09-02 12:45:45
什么是迭代器
迭代是 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 实际上是一个列表,但是被迭代器迭代之后。并不是一次性将列表放入内存中,而是每次放一个元素进入内存,然后被读取。(这就是我们说的按需加载)
可迭代的对象
类似于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
注意:超过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
注意: 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个数据,那么读取的速度会很快。可能对资源(也就是我们的内存)占用的消耗不是很大;如果我们有一个成千上万甚至十万数据的列表,那么这些数据都要一次性的写入内存里,这么多的数据所消耗占用的资源必然会很大,甚至会撑爆我们的内存造成内存溢出,程序就会报错了。
所以如果通过迭代器的方式,我们只需要用到一个数据就将一个数据扔到内存里并且被使用。这样既可以提高我们内存使用的效率,又可以减少我们内存的消耗。这也是我们平时使用迭代器的目的。
来源:https://blog.csdn.net/weixin_42250835/article/details/123887683
猜你喜欢
- python的代码错误检查通常用pep8、pylint和flake8,自动格式化代码通常用autopep8、yapf、black。这些工具均
- 摘要: 阐述一种全新的ASP模板引擎,实现代码(逻辑)层与HTML(表现)层的分离.这种模板实现方法避免了一般ASP模板加载模板文件(加载组
- Dreamweaver快捷键大全,记住一些常用的快捷键会大大提高你的网页设计效率,如果你都使用快捷键,那么如果你去面试工作就容易被录取,呵呵
- 本文实例讲述了SESSION存放在数据库用法。分享给大家供大家参考。具体如下:<?php/*CREATE TABLE `ws_sess
- 在昨天关于substring的blog中有如下一段代码:也许你已经发现,在Python 3中其实有办法只用一行完成函数:>>&g
- 本文实例为大家分享了python实现猜单词游戏的具体代码,供大家参考,具体内容如下0.效果1.代码# 猜单词游戏import random
- 首先,建一个文件夹,把你要隐藏的文件放在里面,你的所有黑客程序什么的。假设你建的文件夹叫hacker然后呢,我们给这个文件夹加个扩展名(后缀
- 单例模式概念单例模式:“保证一个类仅有一个实例,并提供一个访问它的在这里插入代码片全局访问点。单例模式会阻止其他对象实例化其自己的单例对象的
- 调试JavaScript程序时,有时需要打印函数调用的栈信息,这可以通过使用console.trace()来实现。以下面的代码为例:func
- 一,通用的ASCII码对照表 图解ASCII码对照表图,以字符A为例Dec表示十进制,如65Hx表示十六进制,如41Oct表示八进制,如10
- 本文实例为大家分享了PyQt5如何能够创建在桌面屏幕上居中窗口的具体代码,供大家参考,具体内容如下下面的脚本说明我们如何能够创建在桌面屏幕上
- 概述今天我们要来做一个进阶的花分类问题. 不同于之前做过的鸢尾花, 这次我们会分析 102 中不同的花. 是不是很上头呀.预处理导包常规操作
- 本文实例讲述了JS生成一维码(条形码)功能的方法。分享给大家供大家参考,具体如下:1、js代码:(function() { if (!exp
- 在python处理数据时,经常用到DataFrame和set。train=pd.read_csv('XXX.csv')#读取
- 目录生活中的例子慢查询如何去优化countlimit最大值最小值min&max生活中的例子我们是否看到过在公司中许多查询语句都是se
- 引言 在编写接口自动化测试脚本时,有时我们需要在代码中定
- 一台服务器上开启了3个mysql实例进程,占用不同的端口 3306、3307、3308原理说明:通过自动发现规则来获取MySQL实例的端口,
- 实现效果UI组件依然是使用 Quasar Framework。先来看一下效果:加减.gifinput type="number&q
- 在客户端,Get方式在通过URL提交数据,数据在URL中可以看到;POST方式,数据放置在HTML HEADER内提交。GET方式提交的数据
- 如何阻止别人非法链接你网站的图片,防盗链?getimage.asp<% Option ExplicitDim&nb