迭代器

迭代是访问元素集的一种方式。迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退

可迭代对象

我们已经知道可以对list、tuple、str等类型的数据使用for…in…的循环语法从其中依次拿到数据进行使用,我们把这样的过程称为遍历,也叫迭代

但是,是否所有的数据类型都可以放到for…in…的语句中,然后让for…in…每次从中取出一条数据供我们使用,即供我们迭代吗?

  • 可以使用 isinstance()判断一个对象是否是 Iterable 对象
a = list()      # Iterable可迭代对象
print(isinstance(a, Iterable))  # isinstance(要判断的对象,类型)

输出:True

b = 100
print(isinstance(b, Iterable))   #  输出 False
# int整型不是iterable,即int整型不是可以迭代的

可迭代对象的本质

我们分析对可迭代对象进行迭代使用的过程,发现每迭代一次(即在for…in…中每循环一次)都会返回对象中的下一条数据,一直向后读取数据直到迭代了所有数据后结束。那么,在这个过程中就应该有一个“人”去记录每次访问到了第几条数据,以便每次迭代都可以返回下一条数据。我们把这个能帮助我们进行数据迭代的“人”称为迭代器(Iterator)

可迭代对象的本质就是可以向我们提供一个这样的中间“人”即迭代器帮助我们对其进行迭代遍历使用。

可迭代对象通过__iter__方法向我们提供一个迭代器,我们在迭代一个可迭代对象的时候,实际上就是先获取该对象提供的一个迭代器,然后通过这个迭代器来依次获取对象中的每一个数据.

那么也就是说,一个具备了__iter__方法的对象,就是一个可迭代对象。

from collections import Iterableclass Classmate():def __init__(self):self.names = list()def add(self, name):self.names.append(name)def __iter__(self):  # 该方法的返回值是一个迭代器print("我是iter方法")# return self

iter()函数与next()函数

list、tuple等都是可迭代对象,我们可以通过iter()函数获取这些可迭代对象的迭代器。然后我们可以对获取到的迭代器不断使用next()函数来获取下一条数据。iter()函数实际上就是调用了可迭代对象的__iter__方法。

a = [11, 22, 33, 44, 55]
a_iter = iter(a)  # 获得列表a的迭代器
print(next(a_iter))  # next(迭代器) 取出迭代器中的数据
print(next(a_iter))

注意,当我们已经迭代完最后一个数据之后,再次调用next()函数会抛出StopIteration的异常,来告诉我们所有数据都已迭代完成,不用再执行next()函数了。

迭代器Iterator

我们已经知道,迭代器是用来帮助我们记录每次迭代访问到的位置,当我们对迭代器使用next()函数的时候,迭代器会向我们返回它所记录位置的下一个位置的数据。实际上,在使用next()函数的时候,调用的就是迭代器对象的__next__方法.所以,我们要想构造一个迭代器,就要实现它的__next__方法。但这还不够,python要求迭代器本身也是可迭代的,所以我们还要为迭代器实现__iter__方法,而__iter__方法要返回一个迭代器,迭代器自身正是一个迭代器,所以迭代器的__iter__方法返回自身即可。

一个实现了__iter__方法和__next__方法的对象,就是迭代器。

class MyList(object):"""自定义的一个可迭代对象"""def __init__(self):self.items = []def add(self, val):self.items.append(val)def __iter__(self):     # 有__iter__方法,该类的实例对象是一个可迭代对象myiterator = MyIterator(self)return myiteratorclass MyIterator(object):"""自定义的供上面可迭代对象使用的一个迭代器"""def __init__(self, mylist):self.mylist = mylist# current用来记录当前访问到的位置self.current = 0def __next__(self):    #  有__next__方法 ,有__iter__方法,所以该类的实例对象是一个迭代器if self.current < len(self.mylist.items):item = self.mylist.items[self.current]self.current += 1return itemelse:raise StopIterationdef __iter__(self):  # 为什么该类要有__iter__方法,因为迭代器自身也要求是可迭代的return selfif __name__ == '__main__':mylist = MyList()  # 一个可迭代对象mylist.add(1)mylist.add(2)mylist.add(3)mylist.add(4)mylist.add(5)for num in mylist: # 遍历这个对象print(num)

for…in…循环的本质

for item in Iterable 循环的本质就是先通过iter()函数获取可迭代对象Iterable的迭代器,然后对获取到的迭代器不断调用next()方法来获取下一个值并将其赋值给item,当遇到StopIteration的异常后循环结束。

迭代器的应用场景

我们发现迭代器最核心的功能就是可以通过next()函数的调用来返回下一个数据值。如果每次返回的数据值不是在一个已有的数据集合中读取的,而是通过程序按照一定的规律计算生成的,那么也就意味着可以不用再依赖一个已有的数据集合,也就是说不用再将所有要迭代的数据都一次性缓存下来供后续依次读取,这样可以节省大量的存储(内存)空间。

from collections import Iterableclass Classmate():def __init__(self):self.names = list()def add(self, name):self.names.append(name)def __iter__(self):  # 该方法的返回值是一个迭代器print("我是iter方法")return ClassIterble(self)class ClassIterble():def __init__(self, item):self.item = itemself.c = 0def __iter__(self):passdef __next__(self):if self.c < len(self.item.names):re = self.item.names[self.c]self.c += 1return reelse:raise StopIterationc = Classmate()
c.add("1")
c.add("2")
c.add("3")
for name in c:print(name)

改进一下,让迭代器返回自身,一个类自己是可迭代对象,也是迭代器

from collections import Iterable
from collections import Iterator
import timeclass Classmate:def __init__(self):self.names = list()self.count = 0def add(self, item):self.names.append(item)def __iter__(self):return selfdef __next__(self):if self.count < len(self.names):re = self.names[self.count]self.count += 1return reelse:raise StopIterationc = Classmate()c.add("第一")
c.add("第二")
c.add("第三")
c.add("第四")
for i in c:print(i)time.sleep(1)
lsi = [i for i in c]
print(lsi)

python3高级 一 迭代器相关推荐

  1. Python3 中打的迭代器与生成器

    迭代器 迭代是Python最强大的功能之一,是访问集合元素的一种方式. 迭代器是一个可以记住遍历的位置的对象. 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退 ...

  2. Python3高级篇

    Python3 正则表达式 正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配. Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式. ...

  3. python3生成器与迭代器_Python3迭代器与生成器

    迭代器 迭代是Python最强大的功能之一,是访问集合元素的一种方式. 迭代器是一个可以记住遍历的位置的对象. 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退 ...

  4. python3高级 之 生成器

    生成器 利用迭代器,我们可以在每次迭代获取数据(通过next()方法)时按照特定的规律进行生成.但是我们在实现一个迭代器时,关于当前迭代到的状态需要我们自己记录,进而才能根据当前状态生成下一个数据.为 ...

  5. python3生成器与迭代器_python3迭代器和生成器 | 吴老二

    迭代函数就是一个利用for...in来完成的一个过程,但是呢?在没说迭代函数之前我们需要了解一下什么是迭代器,什么是生成器,两者的区别是什么,先一个一个的学习. 迭代器 先学习一下什么是迭代器,迭代器 ...

  6. Python3 高级特性

    切片 L[0:3]表示,从索引0开始取,直到索引3为止,但不包括索引3.即索引0,1,2,正好是3个元素. 如果第一个索引是0,还可以省略: >>> L =['Michael', ' ...

  7. python高级特性:迭代器与生成器

    前言 有一个列表 l = ['a','b','c','d','e'] 我想取列表中的内容,有几种方式? # 1.最简单的方法用for循环. for i in l:print(i,end=" ...

  8. Python3 高级编程技巧(部分)

    目录: 在列表.字典.集合中筛选数据 为元组元素命名 通过列表.元组创建字典 字典排序 寻找字典的公共键 让字典保持有序 生成器函数 yield协程 同时遍历值与下标 在列表.字典.集合中筛选数据 很 ...

  9. 【python3 高级编程】.一文搞懂多线程

    1.2.1 多线程介绍 线程是程序执行流的最小单元. 线程由线程id,当前计算机的指令指针,寄存器集合和堆栈组成. 线程是一个实体,被系统独立调度和分派的基本单位 1.2.2 线程模块 1.pytho ...

最新文章

  1. kindeditor 批量上传 路径_FtpClient 实现文件上传
  2. python连通域标记_pythonamp;#8212;二值图像连通域标记 - 易采站长站
  3. 【Qt】使用QProcess调用其它程序或脚本
  4. java邻接表无向图的创建_无向图的邻接表创建以及图的深度和…
  5. Kafka分区分配策略(Partition Assignment Strategy
  6. HDU3065 AC自动机
  7. 细述 wxWindows
  8. 晨风机器人回复词库_晨风qq机器人词库下载2015 最新完整版
  9. padavan支持惠普打印服务器,【完美解决】openwrt共享hp1020打印机,HP/惠普打印机_好文分享_优购 - 荐优,购适...
  10. Atheros对Ralink,看WiFi产品的射频电路设计
  11. 计算器计算经纬距离_经纬距离计算器下载_经纬距离计算器官方下载-太平洋下载中心...
  12. 最有用的25个 Matplotlib图(含Python代码模板)
  13. Android笔记:自定义锁屏
  14. 家用计算机硬件升级方案,旧电脑如何升级提速,老电脑升级方案!
  15. 成人高考 计算机英语作文,「2017成人高考高起专英语作文」求成人考试英语作文4篇!...
  16. 7 Workflow
  17. matlab如何去除图像白边_matlab 图像保存时去除白边
  18. 微信公众号开发完整教程(一) PHP7.0版本,TP5.0框架
  19. harbor2.1.1配置反向代理
  20. B. Combinatorics Homework(抽屉原理)

热门文章

  1. python爬虫系列(3.8-正则的使用)
  2. Unity应用架构设计(10)——绕不开的协程和多线程(Part 1)
  3. html页面顶部提示在更高浏览器下面提示语
  4. 关于aspx.designer.cs
  5. 使用Qt Creator 2.60编写C/C++程序
  6. 【Android 应用开发】Android资源文件 - 使用资源存储字符串 颜色 尺寸 整型 布尔值 数组...
  7. magic_quotes_gpc与magic_quotes_runtime区别
  8. Exchange 2007 删除 某时间段 特定主题 的邮件
  9. 网域高科家具行业网站开发管理系统
  10. 面试精讲之面试考点及大厂真题 - 分布式专栏 11 Redis热点key大Value解决方案