Skip to content
SRE运维进阶之路SRE运维进阶之路
github icon
    • 1 Python 简介

      • 1.1 初识Python
        • 1.2 Python 代码规范
          • 1.3 Python 虚拟环境
            • 1.4 使用 vscode 打造 python 开发环境
              • 1.5 pypi 配置国内镜像
              • 2 Python 基础

                • 2.1 Python基础语法
                  • 2.2 程序控制
                    • 2.3 Python数据类型

                      • 2.3.1 数值型
                        • 2.3.2 字符串 str
                          • 2.3.3 字节序列
                            • 2.3.4 列表 list & 元组 tuple
                              • 2.3.5 集合 set & 字典 dict
                            • 3 高级特性

                              • 3.1 线性结构特征 可迭代 & 切片
                                • 3.2 列表、集合、字典解析式
                                  • 3.3 生成器
                                    • 3.4 迭代器
                                    • 4 函数

                                      • 4.1 函数的定义 & 调用 & 返回值
                                        • 4.2 函数参数
                                          • 4.3 作用域
                                            • 4.4 递归函数
                                            • 5 函数式编程

                                              • 5.1 高阶函数
                                                • 5.2 返回函数
                                                  • 5.3 匿名函数
                                                    • 5.4 装饰器
                                                      • 5.5 偏函数
                                                      • 6 模块

                                                        • 6.1 Python 模块常用的几种安装方式
                                                          • 6.2 Python 的 setup.py 详解
                                                          • 7 IO编程

                                                            • 7.1 操作文件和目录
                                                              • 7.2 序列化和反序列化
                                                              • 8 异常、调试和测试

                                                                • 8.1 异常处理
                                                                • 9 面向对象编程

                                                                  • 9.1 类、实例和封装
                                                                    • 9.2 访问控制和属性装饰器
                                                                      • 9.3 继承、多态和Mixin
                                                                      • 10 进程和线程

                                                                        • 10.1 多进程
                                                                          • 10.2 多线程
                                                                            • 10.2 线程同步
                                                                            • 11 网络编程

                                                                              • 11.1 SocketServer
                                                                                • 11.2 TCP 编程
                                                                                • 11 魔术方法
                                                                                  • 17 IO 模型
                                                                                    • python 实际工作中的实例
                                                                                    • 前端学习笔记

                                                                                      3.4 迭代器

                                                                                      author iconClaycalendar icon2021年6月22日category icon
                                                                                      • Python
                                                                                      timer icon大约 3 分钟

                                                                                      # 3.4 迭代器

                                                                                      我们已经知道,可以直接作用于for循环的数据类型有以下几种:

                                                                                      一类是集合数据类型,如list、tuple、dict、set、str等;

                                                                                      一类是generator,包括生成器和带yield的generator function。

                                                                                      这些可以直接作用于for循环的对象统称为可迭代对象:Iterable。

                                                                                      可以使用isinstance()判断一个对象是否是Iterable对象:

                                                                                      >>> from collections.abc import Iterable
                                                                                      >>> isinstance([], Iterable)
                                                                                      True
                                                                                      >>> isinstance({}, Iterable)
                                                                                      True
                                                                                      >>> isinstance('abc', Iterable)
                                                                                      True
                                                                                      >>> isinstance((x for x in range(10)), Iterable)
                                                                                      True
                                                                                      >>> isinstance(100, Iterable)
                                                                                      False
                                                                                      
                                                                                      1
                                                                                      2
                                                                                      3
                                                                                      4
                                                                                      5
                                                                                      6
                                                                                      7
                                                                                      8
                                                                                      9
                                                                                      10
                                                                                      11

                                                                                      而生成器不但可以作用于for循环,还可以被next()函数不断调用并返回下一个值,直到最后抛出StopIteration错误表示无法继续返回下一个值了。

                                                                                      可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。

                                                                                      可以使用isinstance()判断一个对象是否是Iterator对象:

                                                                                      >>> from collections.abc import Iterator
                                                                                      >>> isinstance((x for x in range(10)), Iterator)
                                                                                      True
                                                                                      >>> isinstance([], Iterator)
                                                                                      False
                                                                                      >>> isinstance({}, Iterator)
                                                                                      False
                                                                                      >>> isinstance('abc', Iterator)
                                                                                      False
                                                                                      
                                                                                      1
                                                                                      2
                                                                                      3
                                                                                      4
                                                                                      5
                                                                                      6
                                                                                      7
                                                                                      8
                                                                                      9

                                                                                      生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。

                                                                                      把list、dict、str等Iterable变成Iterator可以使用iter()函数:

                                                                                      >>> isinstance(iter([]), Iterator)
                                                                                      True
                                                                                      >>> isinstance(iter('abc'), Iterator)
                                                                                      True
                                                                                      
                                                                                      1
                                                                                      2
                                                                                      3
                                                                                      4

                                                                                      你可能会问,为什么list、dict、str等数据类型不是Iterator?

                                                                                      这是因为Python的Iterator对象表示的是一个数据流,Iterator对象可以被next()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以Iterator的计算是惰性的,只有在需要返回下一个数据时它才会计算。

                                                                                      Iterator甚至可以表示一个无限大的数据流,例如全体自然数。而使用list是永远不可能存储全体自然数的。

                                                                                      小结

                                                                                      凡是可作用于for循环的对象都是Iterable类型;

                                                                                      凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;

                                                                                      集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。

                                                                                      Python的for循环本质上就是通过不断调用next()函数实现的,例如:

                                                                                      for x in [1, 2, 3, 4, 5]:
                                                                                          pass
                                                                                      
                                                                                      1
                                                                                      2

                                                                                      实际上完全等价于:

                                                                                      # 首先获得Iterator对象:
                                                                                      it = iter([1, 2, 3, 4, 5])
                                                                                      # 循环:
                                                                                      while True:
                                                                                          try:
                                                                                              # 获得下一个值:
                                                                                              x = next(it)
                                                                                          except StopIteration:
                                                                                              # 遇到StopIteration就退出循环
                                                                                              break
                                                                                      
                                                                                      1
                                                                                      2
                                                                                      3
                                                                                      4
                                                                                      5
                                                                                      6
                                                                                      7
                                                                                      8
                                                                                      9
                                                                                      10

                                                                                      迭代器

                                                                                      • 特殊的对象,一定是可迭代对象,具备可迭代对象的特征
                                                                                      • 通过 iter 方法把一个可迭代对象封装成迭代器
                                                                                      • 通过 next 方法,迭代 迭代器对象
                                                                                      • 生成器对象,就是迭代器对象。但是迭代器对象未必是生成器对象

                                                                                      可迭代对象

                                                                                      • 能够通过迭代一次次返回不同的元素的对象
                                                                                        • 所谓相同,不是指值是否相同,而是元素在容器中是否是同一个,例如列表中值可以重复的,['a', 'a'],虽然这个列表有2个元素,值一样,但是两个'a'是不同的元素
                                                                                      • 可以迭代,但是未必有序,未必可索引
                                                                                      • 可迭代对象有:list、tuple、string、bytes、bytearray、range、set、dict、生成器、迭代器等
                                                                                      • 可以使用成员操作符in、not in
                                                                                        • 对于线性数据结构,in本质上是在遍历对象,时间复杂度为O(n)
                                                                                      lst = [1, 3, 5, 7, 9]
                                                                                      it = iter(lst) # 返回一个迭代器对象
                                                                                      print(next(it)) # 1
                                                                                      print(next(it)) # 3
                                                                                      for i, x in enumerate(it, 2):
                                                                                          print(i, x)
                                                                                      #2 5
                                                                                      #3 7
                                                                                      #4 9
                                                                                      
                                                                                      # print(next(it)) # StopIteration
                                                                                      print()
                                                                                      
                                                                                      for x in reversed(lst):
                                                                                          print(x) # 9 7 5 3 1
                                                                                      
                                                                                      1
                                                                                      2
                                                                                      3
                                                                                      4
                                                                                      5
                                                                                      6
                                                                                      7
                                                                                      8
                                                                                      9
                                                                                      10
                                                                                      11
                                                                                      12
                                                                                      13
                                                                                      14
                                                                                      15
                                                                                      edit icon编辑此页open in new window
                                                                                      上次编辑于: 2021/6/23 03:40:27
                                                                                      贡献者: clay-wangzhi
                                                                                      上一页
                                                                                      3.3 生成器
                                                                                      备案号:冀ICP备2021007336号
                                                                                      Copyright © 2023 Clay