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查找第k小元素代码分享
Dec 18 Python
Python实现统计单词出现的个数
May 28 Python
python中使用序列的方法
Aug 03 Python
浅析Python基础-流程控制
Mar 18 Python
python 获取当天凌晨零点的时间戳方法
May 22 Python
python实现对任意大小图片均匀切割的示例
Dec 05 Python
OpenCV搞定腾讯滑块验证码的实现代码
May 18 Python
python使用Qt界面以及逻辑实现方法
Jul 10 Python
Pycharm 文件更改目录后,执行路径未更新的解决方法
Jul 19 Python
Python箱型图绘制与特征值获取过程解析
Oct 22 Python
Python 实现定积分与二重定积分的操作
May 26 Python
Python数组变形的几种实现方法
May 30 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
150kHz到30Mhz完全冲浪手册
2020/03/20 无线电
Smarty安装配置方法
2008/04/10 PHP
PHP中设置时区,记录日志文件的实现代码
2013/01/07 PHP
老生常谈PHP面向对象之命令模式(必看篇)
2017/05/24 PHP
详解强大的jQuery选择器之基本选择器、层次选择器
2012/02/07 Javascript
Javascript创建自定义对象 创建Object实例添加属性和方法
2012/06/04 Javascript
jquery $.each() 使用小探
2013/08/23 Javascript
JS实现将人民币金额转换为大写的示例代码
2014/02/13 Javascript
js中的getAttribute方法使用示例
2014/08/01 Javascript
浅谈$(document)和$(window)的区别
2015/07/15 Javascript
JavaScript数组各种常见用法实例分析
2015/08/04 Javascript
js实现登录框鼠标拖拽效果
2017/03/09 Javascript
vue-quill-editor实现图片上传功能
2017/08/08 Javascript
layui 优化button按钮和弹出框的方法
2018/08/15 Javascript
详解Vue结合后台的列表增删改案例
2018/08/21 Javascript
深入理解nodejs搭建静态服务器(实现命令行)
2019/02/05 NodeJs
python线程池的实现实例
2013/11/18 Python
python中合并两个文本文件并按照姓名首字母排序的例子
2014/04/25 Python
python3学习之Splash的安装与实例教程
2018/07/09 Python
Python3爬虫之urllib携带cookie爬取网页的方法
2018/12/28 Python
python3模拟实现xshell远程执行liunx命令的方法
2019/07/12 Python
python实现几种归一化方法(Normalization Method)
2019/07/31 Python
Tensorflow训练模型越来越慢的2种解决方案
2020/02/07 Python
Python2.x与3​​.x版本有哪些区别
2020/07/09 Python
某公司C#程序员面试题笔试题
2014/05/26 面试题
经典的班主任推荐信
2013/10/28 职场文书
幼儿园保育员辞职信
2014/01/12 职场文书
工作作风承诺书
2014/08/30 职场文书
批评与自我批评发言稿
2014/10/15 职场文书
2015年元旦晚会活动总结(学生会)
2014/11/28 职场文书
2014年高数考试作弊检讨书
2014/12/14 职场文书
2014年党总支工作总结
2014/12/18 职场文书
导游词之镇江焦山
2019/11/21 职场文书
Nginx + consul + upsync 完成动态负载均衡的方法详解
2021/03/31 Servers
python基础学习之递归函数知识总结
2021/05/26 Python
Windows server 2012 R2 安装IIS服务器
2022/04/29 Servers