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双向链表实现实例代码
Nov 21 Python
Python中请使用isinstance()判断变量类型
Aug 25 Python
Python+django实现简单的文件上传
Aug 17 Python
python psutil库安装教程
Mar 19 Python
使用实现pandas读取csv文件指定的前几行
Apr 20 Python
使用Python进行QQ批量登录的实例代码
Jun 11 Python
获取python的list中含有重复值的index方法
Jun 27 Python
Caffe均值文件mean.binaryproto转mean.npy的方法
Jul 09 Python
Python tkinter的grid布局及Text动态显示方法
Oct 11 Python
Python HTTP下载文件并显示下载进度条功能的实现
Apr 02 Python
python爬虫学习笔记之pyquery模块基本用法详解
Apr 09 Python
python 标准库原理与用法详解之os.path篇
Oct 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
当海贼王变成JOJO风
2020/03/02 日漫
深入解析PHP垃圾回收机制对内存泄露的处理
2013/06/14 PHP
解析用PHP实现var_export的详细介绍
2013/06/20 PHP
php实现分页工具类分享
2014/01/09 PHP
PHP访问Google Search API的方法
2015/03/05 PHP
php通过curl添加cookie伪造登陆抓取数据的方法
2016/04/02 PHP
用php+ajax新建流程(请假、进货、出货等)
2017/06/11 PHP
HTML-CSS群中单选引发的“事件”
2007/03/05 Javascript
Javascript Select操作大集合
2009/05/26 Javascript
Jquery 组合form元素为json格式,asp.net反序列化
2009/07/09 Javascript
js实现鼠标拖动图片并兼容IE/FF火狐/谷歌等主流浏览器
2013/06/06 Javascript
js跑步算法的实现代码
2013/12/04 Javascript
Jquery EasyUI中弹出确认对话框以及加载效果示例代码
2014/02/13 Javascript
轻松创建nodejs服务器(8):非阻塞是如何实现的
2014/12/18 NodeJs
Bootstrap jquery.twbsPagination.js动态页码分页实例代码
2017/02/20 Javascript
JavaScript数据结构之优先队列与循环队列实例详解
2017/10/27 Javascript
Vue-cli 使用json server在本地模拟请求数据的示例代码
2017/11/02 Javascript
vue改变循环遍历后的数据实例
2019/11/07 Javascript
angular异步验证防抖踩坑实录
2019/12/01 Javascript
[07:52]2014DOTA2 TI逗比武士游V社解说背后的故事
2014/07/10 DOTA
[46:12]完美世界DOTA2联赛循环赛 DM vs Matador BO2第一场 11.04
2020/11/04 DOTA
基于Python实现的ID3决策树功能示例
2018/01/02 Python
Numpy数组array和矩阵matrix转换方法
2019/08/05 Python
django创建简单的页面响应实例教程
2019/09/06 Python
Python如何使用字符打印照片
2020/01/03 Python
Python单链表原理与实现方法详解
2020/02/22 Python
django实现日志按日期分割
2020/05/21 Python
html5 利用canvas手写签名并保存的实现方法
2018/07/12 HTML / CSS
html5 实现客户端验证上传文件的大小(简单实例)
2016/05/15 HTML / CSS
车间班长岗位职责
2013/11/30 职场文书
政治学专业毕业生求职信
2014/08/11 职场文书
2014高中生入党思想汇报范文
2014/09/13 职场文书
党员学习中国梦心得体会
2016/01/05 职场文书
医务人员医德医风心得体会
2016/01/25 职场文书
2016年法制宣传月活动总结
2016/04/01 职场文书
JavaScript实现简单拖拽效果
2021/09/15 Javascript