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 相关文章推荐
Pycharm学习教程(4) Python解释器的相关配置
May 03 Python
django 开发忘记密码通过邮箱找回功能示例
Apr 17 Python
numpy返回array中元素的index方法
Jun 27 Python
示例详解Python3 or Python2 两者之间的差异
Aug 23 Python
python使用pdfminer解析pdf文件的方法示例
Dec 20 Python
利用Python半自动化生成Nessus报告的方法
Mar 19 Python
django 基于中间件实现限制ip频繁访问过程详解
Jul 30 Python
Python Tensor FLow简单使用方法实例详解
Jan 14 Python
python GUI库图形界面开发之PyQt5简单绘图板实例与代码分析
Mar 08 Python
Python库skimage绘制二值图像代码实例
Apr 10 Python
Python批量将csv文件转化成xml文件的实例
May 10 Python
python字符串拼接.join()和拆分.split()详解
Nov 23 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系统流量分析的程序
2006/10/09 PHP
php获取文件夹路径内的图片以及分页显示示例
2014/03/11 PHP
php使用CURL不依赖COOKIEJAR获取COOKIE的方法
2015/06/17 PHP
Joomla简单判断用户是否登录的方法
2016/05/04 PHP
jquery 表格分页等操作实现代码(pagedown,pageup)
2010/04/11 Javascript
Javascript笔记一 js以及json基础使用说明
2010/05/22 Javascript
js 三级关联菜单效果实例
2013/08/13 Javascript
引入JS文件IE6报语法错误或缺少对象问题的解决方法
2014/01/09 Javascript
jQuery解决$符号命名冲突
2016/06/18 Javascript
JavaScript ES6的新特性使用新方法定义Class
2016/06/28 Javascript
angularJS+requireJS实现controller及directive的按需加载示例
2017/02/20 Javascript
JS简单实现获取元素的封装操作示例
2017/04/07 Javascript
使用Vue动态生成form表单的实例代码
2018/04/26 Javascript
vue-cli3.0使用及部分配置详解
2018/08/29 Javascript
vue项目中使用AES实现密码加密解密(ECB和CBC两种模式)
2019/08/12 Javascript
详解用async/await来处理异步
2019/08/28 Javascript
vue-cli3.X快速创建项目的方法步骤
2019/11/14 Javascript
keep-alive保持组件状态的方法
2020/12/02 Javascript
wxPython 入门教程
2008/10/07 Python
Python编程给numpy矩阵添加一列方法示例
2017/12/04 Python
100行python代码实现跳一跳辅助程序
2018/01/15 Python
哪些是python中web开发框架
2020/06/17 Python
使用HTML5原生对话框元素并轻松创建模态框组件
2019/03/06 HTML / CSS
男女时尚与复古风格在线购物:RoseGal(全球免费送货)
2017/07/19 全球购物
高中同学聚会邀请函
2014/01/11 职场文书
运动会广播稿500字
2014/01/28 职场文书
高级销售求职信
2014/02/21 职场文书
写自荐信的注意事项
2014/03/09 职场文书
新学期决心书
2014/03/11 职场文书
优秀团员事迹材料2000字
2014/08/20 职场文书
在职证明书范本(2014新版)
2014/09/25 职场文书
2014-2015学年工作总结
2014/11/27 职场文书
山楂树之恋观后感
2015/06/11 职场文书
浅谈如何提高PHP代码质量之端到端集成测试
2021/05/28 PHP
Django集成富文本编辑器summernote的实现步骤
2021/05/31 Python
深入理解redis中multi与pipeline
2021/06/02 Redis