鄙人学习笔记
开发工具:Spyder


文章目录

  • 迭代
      • 举个例子1
      • 举个例子2
      • for循环原理
    • 可迭代对象iterable
      • 举个例子1
      • 举个例子2
      • 举个例子3
    • 迭代器对象iterator
      • yield关键字迭代原理
      • 举个例子(我们将之前的MyRange类进行改写)

迭代

每一次对过程的重复为一次”迭代”,而每一次迭代得到的结果,会作为下一次迭代的初始值。例如:循环获取容器中的元素。

举个例子1

创建一个列表:

再输入以下代码:


结果:

可以看出,我们得到的结果和for循环遍历这个列表,得到的结果相同。

如果我们多写一个iterator.__next__(),会怎样呢?


结果:

会报错 python警告我们,要 Stop Iteration, 停止迭代!

举个例子2

还是创建原来的列表:

我们再利用以下方法迭代:


第39行代码这样写,其实相当于在except之后写了个异常基类:

结果:

我们发现,我们没有用for循环,也拿到了可迭代对象(列表)内元素。以上两个例子演示了for循环原理。

for循环原理

现在,我们对上面例子中的代码进行解释,进而阐述一下for循环原理

①获取迭代器对象


我们说,可迭代对象,是具有__iter__()方法,可以返回迭代器的对象。所以以后我们评判一个对象是不是可迭代对象时,就可以看一看,这个对象有没有__iter__()方法,如果有这个方法,则说明,这个对象是可以被迭代的。

②获取下一个元素(迭代)


有迭代器之后,我们就可以迭代了,__next__()的过程就是在迭代的过程,有__next__()我们就可以拿到下一个元素。

③停止迭代(StopIteration错误)

最后,我们总结一下for循环原理:

①获取迭代器对象
②循环迭代(调用迭代器的__next__()方法)
③捕获StopIteration异常

  • 小问题

问:能够被for循环的条件是什么?
答:具有__iter__()方法的对象。

  • 例子1

使用while + 迭代器,获取元祖(“小白”, “小黄”, “大白”)中所有元素。

代码:

t01 = ("小白", "小黄", "大白")
iterator = t01.__iter__()while True:try:item = iterator.__next__()print(item)except:break

结果:

  • 例子2

不使用for循环,获取字典{“小白”:0, “小黄”:6, “大白”:7}中的key和value.

代码:

d01 = {"小白":0, "小黄":6, "大白":7}iterator = d01.__iter__()while True:try:key = iterator.__next__()print(key, d01[key])except:break

结果:

备注:使用迭代器迭代字典,拿到的是字典的key

可迭代对象iterable

  • 定义

具有__iter__()函数的对象,可以返回迭代器对象.

  • 语法

创建可迭代对象:

class 可迭代对象名称:def __iter__(self):return 迭代器

使用可迭代对象:

for 变量名 in 可迭代对象:语句
  • 原理
迭代器 = 可迭代对象.__iter__()while True:try:print(迭代器.__next__())except StopIteration:break

举个例子1

首先创建两个类:

再创建SkillManager对象,并试着迭代此对象的成员变量skills:

得到结果:

结果得到了列表内的各个Skill对象。

但是,如果我们只迭代SkillManager对象会怎样呢?我们看看下面这个例子。

举个例子2

利用例子1,创建的两个类:

再创建SkillManager对象,并试着迭代此对象:

运行:

报错!且python提示我们SkillManager对象是个不可迭代的对象。

接下来,我们就要让SkillManager可迭代!

我们先要在SkillManager类里增加一个__iter__()方法,使他变为可迭代对象。 这个__iter__()被调用后,应该返回一个迭代器类对象SkillIterator。这个迭代器类对象里应该有一个__next__()方法,用于返回下一个元素。在__next__()方法里应该抛出一个索引越界异常,当被迭代对象全部迭代完后,再获取下一个元素,则会抛出异常。具体情况,我们看看下面的代码。

现在我们看一下SkillManager类:

再看一下SkillIterator类:

创建对象,并开始利用for循环原理,进行迭代:


我们再运行一下,看一下运行结果:

不错!可迭代对象内元素全部拿到了。

备注1:由上面的过程我们也可以看出,可迭代对象不会直接return它的元素,而是由迭代器return了可迭代对象内的元素。

备注2:若我们用for循环,则它也会先获取迭代器对象,获取完迭代器对象后,再用迭代器对象不断的调用__next__()方法,直到迭代器对象抛出异常,for再进行异常处理。

举个例子3

参照下例代码,定义MyRange类,实现相同效果:


代码:

class MyRangeIterator:def __init__(self, stop):self.stop = stopself.start = 0def __next__(self):if self.start + 1 > self.stop:raise StopIteration()temp = self.startself.start += 1return tempclass MyRange:def __init__(self, stop):self.stop = stopdef __iter__(self):# 创建迭代器对象return MyRangeIterator(self.stop)iterator = MyRange(5)
for item in iterator:print(item)

结果:

备注:谁要被for,谁要就有__iter__()方法,这个方法可以获取迭代器,迭代器内部具体怎么写?看需求!迭代器中有__next__(),可以返回下一个元素。

迭代器对象iterator

  • 定义

可以调用__next__()函数,并返回下一个值得对象。

  • 语法
class 迭代器类名::def __init__(self, 聚合对象):self.聚合对象 = 聚合对象def __next__(self):if 没有元素:raise StopIterationreturn 聚合对象内元素
  • 说明

聚合对象通常是容器对象。

  • 作用

使用者只通过一种方式(for循环),便可以简洁明了获取聚合对象中的各个元素,而又无需了解可迭代对象的内部存储结构。

==备注!==若我们在__iter__()方法内不返回自己创建的迭代器对象,而用yield关键字自动生成迭代器对象,会怎样呢?

请看以下案例

代码:


结果:

执行过程:

①客户端调用__iter__()方法,__iter__()方法不执行, 进入while循环.
②客户端调用__next__()方法,__iter__()方法执行,先执行print("准备返回第一个元素"), 执行到yield语句, 将yield后的数据作为__next__()方法的返回值return给item, 并且暂时离开__iter__()方法, 继续执行while循环中的print(item).
③当再次调用__next__()方法时,从上次离开的代码开始执行,再运行到下一个yield语句,return数据之后,并再次暂时离开.
④待执行完__iter__()方法体,若再次调用__next__()方法,会自动抛出StopIteration异常.

yield关键字迭代原理

  • 原理

如果方法体中包含yield关键字,那么会自动生成迭代器对象.

生成迭代器代码的大致规则:
①将yield关键字前的代码,放到__next__()方法中.
②将yield关键字后的数据,作为__next__()方法的返回值.

举个例子(我们将之前的MyRange类进行改写)

代码:

结果:

若我们不定义类,而只定义包含yield的方法,来满足我们迭代的需求,该怎么做呢?

代码:

结果:

我们说这项技术,就叫做生成器generator函数.

python基础(part15)--迭代相关推荐

  1. Python基础(八)--迭代,生成器,装饰器与元类

    目录 Python基础(八)--迭代,生成器,装饰器与元类 1 迭代 1.1 可迭代对象与迭代器 1.2 自定义迭代类型 1.3 迭代合体 2 生成器 2.1 什么是生成器 2.2 生成器表达式 2. ...

  2. python基础——迭代

    python基础--迭代 如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们称为迭代(Iteration). 在Python中,迭代是通过for .. ...

  3. 第4章 基础知识进阶 第4.1节 Python基础概念之迭代、可迭代对象、迭代器

    第四章 基础知识进阶 第十七节 迭代.可迭代对象.迭代器 一.    引言 本来计划讲完元组和字典后就讲列表解析和字典解析,但要理解列表解析和字典解析,就需要掌握Python的高级的类型迭代器,因此本 ...

  4. Python基础教程:迭代和解析

    Python中的迭代是指按照元素的顺序逐个调用的过程,迭代概念包括:迭代协议.可迭代对象和迭代器三个概念. 迭代协议是指有__next__()函数的对象会前进到下一个结果,而到达系列的末尾时,则会引发 ...

  5. Python入门基础之迭代和列表生成式

    什么是迭代 在Python中,如果给定一个list或tuple,我们可以通过for循环来遍历这个list或tuple,这种遍历我们成为迭代(Iteration). 在Python中,迭代是通过 for ...

  6. python基础04

    python基础04 python2在编译安装时,可以通过参数 -----enable----unicode=ucs2 或 -----enable--unicode=ucs4 分别用于指定使用2个字节 ...

  7. 刻意练习:Python基础 -- Task11. 魔法方法

    背景 我们准备利用17天时间,将 "Python基础的刻意练习" 分为如下任务: Task01:变量.运算符与数据类型(1day) Task02:条件与循环(1day) Task0 ...

  8. 刻意练习:Python基础 -- Task09. else 与 with 语句

    背景 我们准备利用17天时间,将 "Python基础的刻意练习" 分为如下任务: Task01:变量.运算符与数据类型(1day) Task02:条件与循环(1day) Task0 ...

  9. 刻意练习:Python基础 -- Task06. 字典与集合

    背景 我们准备利用17天时间,将 "Python基础的刻意练习" 分为如下任务: Task01:变量.运算符与数据类型(1day) Task02:条件与循环(1day) Task0 ...

最新文章

  1. spring 基于XML的申明式AspectJ通知的执行顺序
  2. 上帝和面向对象的七天
  3. 【FPGA】Spartan-6的时钟管理器(CMT)
  4. 【通知】2020年有三AI-CV夏季划升级倒计时,最后两天
  5. electron 入坑记
  6. java 水印 位置_Java实现图片加水印且控制位置和透明度
  7. C++基础与深度解析第一章:C++初探笔记
  8. log4j指定日志文件目录
  9. VS2015 自动代码补全
  10. 胡昊—第6次作业—static关键字、对象
  11. 火狐浏览器修改默认搜索引擎和添加搜索引擎
  12. 什么是电口模块?它和光模块有什么区别?
  13. Altium Designer 10 PCB简要设计及其例程
  14. c语言窄字符转换为宽字符,将窄字符串转换为宽字符串
  15. 操作Excel之“=VLOOKUP(V2,Sheet2!J:K,2)”公式解读
  16. “有效沟通”-你的团队做到了吗?
  17. Atlas (一) --------- Atlas 入门
  18. 【数字电子技术 Digital Electronic Technology 5】—— 组合逻辑电路设计题解题技巧归纳
  19. 用inkspace创建一个简单的LOGO
  20. 英雄联盟显示计算机内存不足怎么办,为什么我的电脑玩多玩几把LOL就显示内存不足...

热门文章

  1. 大话数据结构22:几种常见的静态查找算法
  2. mysql如何获取句柄_关于获取进程句柄的问题
  3. Jpeglib使用指南, 各种压缩包的压缩和解压方法, 开源社区分裂史
  4. 线性代数导论5——SVD分解
  5. 怎么检测计算机硬件好坏,驱动人生怎么看电脑硬件 硬件检测教程介绍
  6. director.js实现前端路由
  7. NYOJ10: skiing(DFS + DP)
  8. 方立勋_30天掌握JavaWeb_JSP
  9. Ajax基于rest风格上传图片
  10. 每周分享五个 PyCharm 使用技巧(四)