Skip to content

Latest commit

 

History

History
105 lines (71 loc) · 3.59 KB

File metadata and controls

105 lines (71 loc) · 3.59 KB

Attack on Python - 迭代器 🐍

介绍

迭代器一般用于对容器对象进行遍历访问 , 例如我们对 Python 中的 str , list , tuple , dict , set 等对象的遍历都可以通过迭代器进行遍历访问

在介绍迭代器之前 , 我们需要介绍一下可迭代对象

可迭代对象

迭代是重复反馈过程的活动 , 其目的通常是为了逼近所需目标或结果

可迭代对象 , 即可以按照迭代的方式进行存取数据的对象 , 在 Python 中我们可以理解为可以用 for 循环遍历的对象就是可迭代对象

可迭代对象的标志是 , 它具有__iter__()方法

如何判断一个对象为可迭代对象

# 导入模块
>>> from collections import Iterable
>>> l = ['lyon','oldboy']
# 判断是否为Iterable , 即可迭代对象
>>> isinstance(l,Iterable)
# 返回bool值
True

迭代器

for循环做的那些事 : for循环是我们用来遍历一个数据集合的方法 , 其实就是根据一定的要求 (这个要求叫做'协议' ) 进行一次次的迭代的效果 . 当我们用 for 循环去遍历时 , 它做的第一件事就是判断对象是否是可迭代对象 , 如果是 , 那么它就会通过 __iter__ 方法返回一个迭代器 , 最后利用__next__()方法将迭代器中的内容一个接一个的取出来

也就是说在 Python 中 , 迭代器已经内置在语言中了 , 我们可以称这种为隐式迭代器

所以迭代器其实就是遍历访问容器对象的一种工具 , 设计人员不需要关心容器对象的内存分配的实现细节

特点:

  1. 不依赖索引取值 , 访问者不需要关心迭代器内部的结构 , 仅需通过 __next__() 方法去访问
  2. 不能随机访问集合中的某个值 , 只能从头到尾依次访问 , 不可返回访问
  3. 惰性计算 , 只有在需要访问时才会生成值 , 节省内存

Python 中有一个iter()方法 , 作用就是将可迭代对象变成一个迭代器 , 实质上 iter() 是去调用了__iter__()方法 , 看代码:

>>> l = ['lyon']
>>> l.__iter__()
# iterator即迭代器
<list_iterator object at 0x0000026DA649D320>

可迭代对象与迭代器的区别:

# 用dir方法查看对象中的所有方法
>>> dir_list = dir([1,2])
>>> dir_iter = dir([1,2].__iter__())
# 筛选出不同点
>>> set(dir_iter) - set(dir_list)
{'__length_hint__', '__setstate__', '__next__'}

我们可以看出迭代器比可迭代对象多出了三个方法 , 所以我们可以根据这一点来判断一个对象到底是可迭代对象还是一个迭代器

# 创建一个迭代器
>>> i = iter([1,2,3,4])
# 查看迭代器中元素的长度
>>> i.__length_hint__()
4
# 根据索引指定迭代开始位置
>>> i.__setstate__(3)
# 进行取值
>>> i.__next__()
4

判断方法

# 导入Iterable类
>>> from collections import Iterable
# 导入Iterator类
>>> from collections import Iterator
# 是否为可迭代对象
>>> isinstance(obj,Iterable)
# 是否为迭代器
>>> isinstance(obj,Iterator)
# 注意:迭代器也是可迭代对象

在迭代时 , 我们需要注意迭代器中是否有值的问题 , 即当我们一直调用__next__ 方法取值时 , 如果值都取完了 , 而此时我们再执行 __next__ 方法 , 解释器就会抛出 StopIteration , 因为已经没有值可以取了

迭代器的实现 , 一种常见的方式是使用受限的协程 , 就是生成器 , 另外生成器也可以叫做 "半协程"

关于协程的文章 , 你可以在 并发篇 中找到它 , 下一章我们会介绍 Python 的生成器