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实现文件快照加密保护的方法
Jun 30 Python
Python选课系统开发程序
Sep 02 Python
Python读取mat文件,并转为csv文件的实例
Jul 04 Python
Python基于多线程操作数据库相关问题分析
Jul 11 Python
Python内存读写操作示例
Jul 18 Python
Django web框架使用url path name详解
Apr 29 Python
10款最好的Python开发编辑器
Jul 03 Python
Django 反向生成url实例详解
Jul 30 Python
使用 Django Highcharts 实现数据可视化过程解析
Jul 31 Python
jenkins配置python脚本定时任务过程图解
Oct 29 Python
对Tensorflow中tensorboard日志的生成与显示详解
Feb 04 Python
Python语言中的数据类型-序列
Feb 24 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
帅气的琦玉老师
2020/03/02 日漫
建立文件交换功能的脚本(一)
2006/10/09 PHP
php通过文件头检测文件类型通用代码类(zip,rar等)
2010/10/19 PHP
php数字转汉字代码(算法)
2011/10/08 PHP
几道坑人的PHP面试题 试试看看你会不会也中招
2014/08/19 PHP
[原创]PHP简单开启curl的方法(测试可行)
2016/01/11 PHP
php打开本地exe程序,js打开本地exe应用程序,并传递相关参数方法
2018/02/06 PHP
PHP框架实现WebSocket在线聊天通讯系统
2019/11/21 PHP
js实现双向链表互联网机顶盒实战应用实现
2011/10/28 Javascript
js实现一个简单的数字时钟效果
2017/03/29 Javascript
Vue.js组件通信的几种姿势
2017/10/23 Javascript
bootstrap datetimepicker控件位置异常的解决方法
2017/11/23 Javascript
用Object.prototype.toString.call(obj)检测对象类型原因分析
2018/10/11 Javascript
微信小程序实现工作时间段选择
2019/02/15 Javascript
在小程序中推送模板消息的实现方法
2019/07/22 Javascript
vue+elementUI实现简单日历功能
2020/09/24 Javascript
详解webpack的clean-webpack-plugin插件报错
2020/10/16 Javascript
[02:57]DOTA2英雄基础教程 风行者
2014/01/16 DOTA
使用Python脚本将Bing的每日图片作为桌面的教程
2015/05/04 Python
在Python中操作字符串之rstrip()方法的使用
2015/05/19 Python
python制作一个桌面便签软件
2015/08/09 Python
pycharm无法导入本地模块的解决方式
2020/02/12 Python
Win10下安装并使用tensorflow-gpu1.8.0+python3.6全过程分析(显卡MX250+CUDA9.0+cudnn)
2020/02/17 Python
浅谈Python中threading join和setDaemon用法及区别说明
2020/05/02 Python
opencv 实现特定颜色线条提取与定位操作
2020/06/02 Python
python如何支持并发方法详解
2020/07/25 Python
为什么说Ruby是一种真正的面向对象程序设计语言
2012/10/30 面试题
学校门卫工作职责
2013/12/07 职场文书
水污染治理工程专业自荐信
2014/06/21 职场文书
2014年银行工作总结范文
2014/11/12 职场文书
贫民窟的百万富翁观后感
2015/06/09 职场文书
考试后的感想
2015/08/07 职场文书
pandas:get_dummies()与pd.factorize()的用法及区别说明
2021/05/21 Python
聊聊pytorch测试的时候为何要加上model.eval()
2021/05/23 Python
Python极值整数的边界探讨分析
2021/09/15 Python
mysql中数据库覆盖导入的几种方式总结
2022/03/25 MySQL