Python迭代器iterator生成器generator使用解析


Posted in Python onOctober 24, 2019

1. 迭代

根据记录的前面的元素的位置信息 去访问后续的元素的过程 -遍历 迭代

2. 可迭代对象 iterable

如何判断可迭代对象的3种方式

  • 能够被迭代访问的对象 for in
  • 常用可迭代对象-list tuple str
  • from collections import Iterable
  • isinstance(obj, Iterable)

3. 可迭代对象

可迭代对象通过__iter__方法提供一个 可以遍历对象中数据的工具-迭代器

iter(可迭代对象) 可以获取可迭代对象的迭代器

通过迭代器可以迭代访问 数据

next(迭代器) ===== 迭代器对象.__next__()

可迭代对象的本质 提供了一个迭代器(遍历可迭代对象中的数据)

如何获取可迭代对象中的迭代器 迭代器对象 = iter(可迭代对象)

如果通过迭代器访问可迭代对象中下一个元素 元素的值 = next(迭代器对象)

如果迭代器遍历完成 抛出 停止迭代-异常StopIteration

如果需要实现一个迭代器 就需要实现__next__()

4. 迭代器 iterator

-- 迭代器访问可迭代对象中数据 判断对象是否是迭代器类型

from collections import Iterator
isinstance(obj, Iterator)

自己实现

迭代器本身也是可迭代对象 __iter__() 提供迭代器(self)

下一个元素的值 = next(迭代器) =====> __next__()

实现一个可迭代对象

from collections import Iterable
from collections import Iterator
import time


class MylistIterator(object):
  """这是Mylist类型的对应迭代器类型 """
  def __init__(self,data):
    # 需要被便利的数据
    self.data = data
    # 保存用户访问的位置
    self.index = 0

  def __iter__(self):
    """python规定 迭代器是一种可迭代对象"""
    return self

  def __next__(self):
    """next(ml_iterator) 相当于调用迭代器对象的.__next__()"""
    if self.index < len(self.data):
      ret = self.data[self.index]
      self.index += 1
      return ret
    else:
      # 访问完成 应该抛出异常
      raise StopIteration

class Mylist(object):
  """可迭代对象"""
  def __init__(self):
    self.data = [1,2,3,4,5]

  def __iter__(self):
    """提供迭代器"""
    # 返回迭代器对象
    mliter = MylistIterator(self.data)
    return mliter

# ml是一个可迭代类型
ml = Mylist()

# 获取可迭代对象的 迭代器对象
ml_iter = iter(ml)
print(isinstance(ml_iter, Iterator))
for i in ml:
  print(i)
  time.sleep(1)

"""
1 可迭代对象的本质 提供了一个迭代器(遍历可迭代对象中的数据)

2 如何获取可迭代对象中的迭代器 迭代器对象 = iter(可迭代对象)
    实际上相当于 可迭代对象.__iter__()
3 如果通过迭代器访问可迭代对象中下一个元素 元素的值 = next(迭代器对象)








如果迭代器遍历完成 抛出 停止迭代-异常StopIteration
"""
print(isinstance(ml, Iterable))

用迭代器完成斐波那契数列(难点在next)

"""兔子队列 某一项的值是前两项的和
1 1 2 3 5 8
"""

class Fib(object):
  def __init__(self,n):
    """初始化操作"""
    # n代表数列的长度
    self.n = n

    # 下标记录
    self.index = 0

    self.number1 = 0
    self.number2 = 1

  def __iter__(self):
    return self

  def __next__(self):
    """next(迭代器)=== .__next__()"""
    if self.index < self.n:
      ret = self.number1
      self.number1,self.number2 = self.number2,self.number2+self.number1
      self.index += 1
      return ret
    else:
      raise StopIteration

# list() tuple()都可以接收迭代器 并且将遍历到的数据存储到集合中
print(list(Fib(10)))
#
# # 打印斐波那契数列的前10项的值
# # for i in Fib(10):
# #   print(i)
# # 1 通过iter函数获取可迭代对象 Iterable 的迭代器 iterator
# ml_iterator = iter(Fib(1000))
#
# # 2 在循环内部不断调用next(迭代器) 获取下一个元素的值
# # 3 如果迭代完成 会抛出一个停止迭代的异常StopIteration

5. 生成器 generator

生成器是一种特殊的迭代器 --- 是迭代器, 并且有自己的特点

1 创建生成器表达式 [] ----》 (x for x in range(100))

2 生成器函数

凡是有yield关键字的函数都不是普通函数了 而是生成器函数

# 列表推导式
lis=[x for x in range(10)]
print(lis)

# 生成器表达式 中括号变圆括号
data=(x for x in range(10))
print(data)
# 遍历data
for i in data:
  print(i)

结果:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
<generator object <genexpr> at 0x02AE7120>
1
3
5
7
9

6. yield关键字的作用

挂起当前函数 将后面表达式的值 返回到调用生成器的地方

接收数据 并唤醒当前函数 并且紧接着上次运行的地址继续执行

7. 唤醒生成器的两种方式

生成器.send("数据")

next(生成器) === 生成器.send(None)

在第一次调用生成器对象的是 必须使用next()

在后续的情况下 send和next可以混用

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
SublimeText 2编译python出错的解决方法(The system cannot find the file specified)
Nov 27 Python
Python标准库之循环器(itertools)介绍
Nov 25 Python
python文件读写操作与linux shell变量命令交互执行的方法
Jan 14 Python
Python 查找字符在字符串中的位置实例
May 02 Python
Python用for循环实现九九乘法表
May 31 Python
python+POP3实现批量下载邮件附件
Jun 19 Python
python操作日志的封装方法(两种方法)
May 23 Python
python3 中的字符串(单引号、双引号、三引号)以及字符串与数字的运算
Jul 18 Python
详解python 利用echarts画地图(热力图)(世界地图,省市地图,区县地图)
Aug 06 Python
python多进程并行代码实例
Sep 30 Python
使用tensorflow框架在Colab上跑通猫狗识别代码
Apr 26 Python
Python移位密码、仿射变换解密实例代码
Jun 27 Python
Python 取numpy数组的某几行某几列方法
Oct 24 #Python
Django和Flask框架优缺点对比
Oct 24 #Python
python命令 -u参数用法解析
Oct 24 #Python
使用python制作游戏下载进度条的代码(程序说明见注释)
Oct 24 #Python
用Python解数独的方法示例
Oct 24 #Python
Python3 sys.argv[ ]用法详解
Oct 24 #Python
window7下的python2.7版本和python3.5版本的opencv-python安装过程
Oct 24 #Python
You might like
PHP的foreach中使用引用时需要注意的一个问题和解决方法
2014/05/29 PHP
ci检测是ajax还是页面post提交数据的方法
2014/11/10 PHP
PHP简单获取视频预览图的方法
2015/03/12 PHP
PHP常见过waf webshell以及最简单的检测方法
2019/05/21 PHP
基于jquery中children()与find()的区别介绍
2013/04/26 Javascript
JavaScript中的console.trace()函数介绍
2014/12/29 Javascript
jquery插件NProgress.js制作网页加载进度条
2015/06/05 Javascript
vue2.0 中#$emit,$on的使用详解
2017/06/07 Javascript
解决Vue2.0自带浏览器里无法打开的原因(兼容处理)
2017/07/28 Javascript
vue中使用echarts制作圆环图的实例代码
2018/07/27 Javascript
从理论角度讨论JavaScript闭包
2019/04/03 Javascript
JS实现灯泡开关特效
2020/03/30 Javascript
JS localStorage存储对象,sessionStorage存储数组对象操作示例
2020/02/15 Javascript
javascript设计模式 ? 组合模式原理与应用实例分析
2020/04/14 Javascript
antd-日历组件,前后禁止选择,只能选中间一部分的实例
2020/10/29 Javascript
js实现滚动条自动滚动
2020/12/13 Javascript
[48:21]Mski vs VGJ.S Supermajor小组赛C组 BO3 第一场 6.3
2018/06/04 DOTA
[00:15]TI9观赛名额抽取
2019/07/10 DOTA
python虚拟环境的安装配置图文教程
2017/10/20 Python
python实现决策树ID3算法的示例代码
2018/05/30 Python
python3实现指定目录下文件sha256及文件大小统计
2019/02/25 Python
python调用并链接MATLAB脚本详解
2019/07/05 Python
Python更改pip镜像源的方法示例
2020/12/01 Python
python使用scapy模块实现ping扫描的过程详解
2021/01/21 Python
如何利用CSS3制作3D效果文字具体实现样式
2013/05/02 HTML / CSS
教你如何一步一步用Canvas写一个贪吃蛇
2018/10/22 HTML / CSS
美国老牌主机服务商:iPage
2016/07/22 全球购物
NBA欧洲商店(法国):NBA Europe Store FR
2016/10/19 全球购物
校园奶茶店创业计划书
2014/01/23 职场文书
法人代表任命书范本
2014/06/05 职场文书
产品陈列协议书(标准版)
2014/09/17 职场文书
中秋节主题班会
2015/08/14 职场文书
爱护公物主题班会
2015/08/17 职场文书
教师廉政准则心得体会
2016/01/20 职场文书
Python利用zhdate模块实现农历日期处理
2022/03/31 Python
JS前端可扩展的低代码UI框架Sunmao使用详解
2022/07/23 Javascript