快速学习Python之迭代器和生成器
迭代器
什么是可迭代对象?
我们知道list
、tuple
、dict
、set
、
str
可以用for循环遍历,这种遍历称为迭代(Iteration),被遍历的list或tuple等被称为可迭代对象。
什么是迭代器( Iterator)
迭代器是一个具有迭代功能的对象,它从集合的第一个元素开始访问,直到所有的元素被遍历完,它有两个基本的方法iter()和next()。其中iter()用来创建迭代器对象,next()用于遍历对象的元素。
迭代器提供了一种不依赖索引取值的方式,适用于遍历元素比较多的集合,不会在内存中再占用一大块内存,而是随着循环每次生成一个,从而节省内存占用。
集合数据类型如 list 、 dict 、 str 等是可迭代的, 但不是迭代器 ,不过可以通过 iter() 函数获得一个 Iterator 对象。
#迭代器=iter(容器)
list01 = [1, 2, 3, 4, 5]
iterator = iter(list01)
在遍历字符串,列表或元组对象时经常会用到迭代器,使用next(),获取其中的所有语法。
next()
函数不断返回下一个数据,直到没有数据时抛出StopIteration
错误。
list02=[1,2,3]
it=iter(list02)
while True:
print(next(it))
#输出结果
1
2
3
Traceback(most recent call last):
File"func_1.py", line 55, in<module>
print(next(it))
StopIteration
可以使用isinstance()
判断一个对象是否可迭代:
from collections.abc import Iterable
print(isinstance([1, 2, 3], Iterable)) # 输出True
自定义迭代器
自定义迭代器,需要再实现两个方法 __iter__()
与 __next__()
。
__iter__()
方法返回迭代器对象本身,__next__()
方法返回下一个元素。for语句就是通过__iter__()
方法来获得迭代器对象,接着不停的调用迭代器对象的__next__()
方法,循环遍历取值。
生成器
生成器是一个函数,普通函数用 return 返回一个值,如果一个函数用yield返回值,就叫生成器函数。函数被调用时会返回一个生成器对象。这个生成器对象自动实现了__iter__()
与 __next__()
,生成器是一种特殊的迭代器。
生成器函数和普通函数的区别:
普通函数遇到return
语句或者最后一行语句就返回。而变成生成器函数,调用的时候返回的是生成器对象。在每次调用next()
或用for语句进行下一次迭代时才执行,遇到yield
语句停止,再次执行时从停止的地方继续执行,直到遇到下一个yield
语句。
def func(n):
for i in range(n):
yield i
#调用该函数
func(5)
<generatorobjectfuncat 0x000001E76A903B48> #返回的是生成器对象
#查看该对象中包含的方法
print(dir(func(5)))
['__class__', '__del__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__name__', '__ne__', '__new__', '__next__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'close', 'gi_code', 'gi_frame', 'gi_running', 'gi_yieldfrom', 'send', 'throw']
f=func(5)
print(next(f)) #0
print(next(f)) #1
使用生成器的好处
假设创建了一个包含1000个元素的列表,这1000个元素都放在内存中会占用很大的存储空间。而生成器并不是一上来就把所有值加载进内存,而是你要用几个元素,它才会把这些元素一个个读出来,大大节约了内存。
生成器表达式
有一种非常简便的方式创建生成器,就是生成器表达式。
生成器= (操作 for 元素 in 可迭代对象 )
list03=(x*2 for x in range(5)) #生成列表
for i in list03:
print(i) #输出0 2 4 6 8
- jenkins配置记录(1)--添加用户权限
- jenkins忘记管理员登陆密码的补救措施
- openstack虚拟机迁移的操作记录
- 从MapX到MapXtreme2004[11]-坐标概论
- 动态控件的新思路
- 独家分享 腾讯大神教你如何学习一门新的编程语言-以Python 为例
- 连续打印问题的解决
- 分布式监控系统Zabbix--完整安装记录-批量添加主机和自动发现端口
- 更新Mapx地图的字段
- 设置linux账号的有效时间
- relative定位的理解
- shell+curl监控网站页面(域名访问状态),并利用sedemail发送邮件
- 写稿机器人获“吴文俊奖”,能提升今日头条内容质量吗
- 使用jQuery自动缩图片 - [jQuery]
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 【Java】09 List 集合与 Collections 工具类
- PAT (Advanced Level) Practice 1003 Emergency (25 分)
- 数据结构严书习题6.65已知前中序,求二叉链表
- 【Java】10 Deque 接口
- 12.深入k8s:kubelet创建pod流程源码分析
- (较为详细)树的遍历方式一览(附完整源码可在VScode与cb运行)
- 【Java】12 Map 集合
- 【Java】11 Set 集合
- 4.表格-HTML基础
- 2.语义化-HTML进阶
- MATLAB 与 C 语言的混合编程
- leetcode树之二叉树的层平均值
- C++雾中风景15:聊聊让人抓狂的Name Mangling
- 【Java】15 File 类
- seaborn更高效的统计图表制作工具