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 相关文章推荐
Python和GO语言实现的消息摘要算法示例
Mar 10 Python
python生成器generator用法实例分析
Jun 04 Python
python清除字符串里非数字字符的方法
Jul 02 Python
python中数据爬虫requests库使用方法详解
Feb 11 Python
神经网络(BP)算法Python实现及应用
Apr 16 Python
Python使用sort和class实现的多级排序功能示例
Aug 15 Python
Python时间和字符串转换操作实例分析
Mar 16 Python
Python操作多维数组输出和矩阵运算示例
Nov 28 Python
tensorflow将图片保存为tfrecord和tfrecord的读取方式
Feb 17 Python
详解python环境安装selenium和手动下载安装selenium的方法
Mar 17 Python
Django REST 异常处理详解
Jul 15 Python
拒绝盗图!教你怎么用python给图片加水印
Jun 04 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
Zend Framework动作控制器用法示例
2016/12/09 PHP
Laravel5.5 手动分页和自定义分页样式的简单实现
2019/10/15 PHP
jquery重复提交请求的原因浅析
2014/05/23 Javascript
javascript框架设计读书笔记之数组的扩展与修复
2014/12/02 Javascript
用js写的一个路由(简单实例)
2016/09/24 Javascript
Angularjs 依赖压缩及自定义过滤器写法
2017/02/04 Javascript
vue文件树组件使用详解
2018/03/29 Javascript
webpack4之SplitChunksPlugin使用指南
2018/06/12 Javascript
Node.js npm命令运行node.js脚本的方法
2018/10/10 Javascript
微信小程序上传文件到阿里OSS教程
2019/05/20 Javascript
七行JSON代码把你的网站变成移动应用过程详解
2019/07/09 Javascript
微信小程序之几种常见的弹框提示信息实现详解
2019/07/11 Javascript
vuex(vue状态管理)的特殊应用案例分享
2020/03/03 Javascript
vue 导航守卫和axios拦截器有哪些区别
2020/12/19 Vue.js
python3.0 字典key排序
2008/12/24 Python
python列表操作之extend和append的区别实例分析
2015/07/28 Python
python开发中range()函数用法实例分析
2015/11/12 Python
Django小白教程之Django用户注册与登录
2016/04/22 Python
Python利用multiprocessing实现最简单的分布式作业调度系统实例
2017/11/14 Python
Python实现的多线程同步与互斥锁功能示例
2017/11/30 Python
Python根据已知邻接矩阵绘制无向图操作示例
2018/06/23 Python
对python for 文件指定行读写操作详解
2018/12/29 Python
Python基于matplotlib画箱体图检验异常值操作示例【附xls数据文件下载】
2019/01/07 Python
python sort、sort_index方法代码实例
2019/03/28 Python
python json 递归打印所有json子节点信息的例子
2020/02/27 Python
Django URL参数Template反向解析
2020/11/24 Python
使用Python爬取Json数据的示例代码
2020/12/07 Python
一款超酷的js+css3实现的3D标签云特效兼容ie7/8/9
2013/11/18 HTML / CSS
CSS3的颜色渐变效果的示例代码
2017/09/29 HTML / CSS
意大利消费电子产品购物网站:SLG Store
2019/12/26 全球购物
2015年社区流动人口工作总结
2015/05/12 职场文书
演讲比赛主持词
2015/06/29 职场文书
小学信息技术教学反思
2016/02/16 职场文书
html5中sharedWorker实现多页面通信的示例代码
2021/05/07 Javascript
MySQL数据库事务的四大特性
2022/04/20 MySQL
SQL Server中T-SQL标识符介绍与无排序生成序号的方法
2022/05/25 SQL Server