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 相关文章推荐
编写同时兼容Python2.x与Python3.x版本的代码的几个示例
Mar 30 Python
仅用500行Python代码实现一个英文解析器的教程
Apr 02 Python
python3实现163邮箱SMTP发送邮件
May 22 Python
Jupyter中直接显示Matplotlib的图形方法
May 24 Python
详解Django+Uwsgi+Nginx的生产环境部署
Jun 25 Python
Python判断是否json是否包含一个key的方法
Dec 31 Python
Python3.5迭代器与生成器用法实例分析
Apr 30 Python
python opencv捕获摄像头并显示内容的实现
Jul 11 Python
使用python无账号无限制获取企查查信息的实例代码
Apr 17 Python
Python爬虫爬取微信朋友圈
Aug 06 Python
python操作redis数据库的三种方法
Sep 10 Python
Python序列化模块JSON与Pickle
Jun 05 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
将数字格式的计算结果转为汉字格式
2006/10/09 PHP
Zend Studio 无法启动的问题解决方法
2008/12/04 PHP
PHP下打开phpMyAdmin出现403错误的问题解决方法
2013/05/23 PHP
php过滤HTML标签、属性等正则表达式汇总
2014/09/22 PHP
PHP标准类(stdclass)用法示例
2016/09/28 PHP
Laravel实现搜索的时候分页并携带参数
2019/10/15 PHP
this和执行上下文实现代码
2010/07/01 Javascript
自写简单JS判断是否已经弹出页面
2010/10/20 Javascript
js 图片随机不定向浮动的实现代码
2013/07/02 Javascript
jQuery自动切换/点击切换选项卡效果的小例子
2013/08/12 Javascript
JavaScript中prototype为对象添加属性的误区介绍
2013/10/15 Javascript
网站繁简切换的JS遇到页面卡死的解决方法
2014/03/12 Javascript
input:checkbox多选框实现单选效果跟radio一样
2014/06/16 Javascript
angularjs实现与服务器交互分享
2014/06/24 Javascript
Javascript中call与apply的学习笔记
2014/09/22 Javascript
js实现网页随机切换背景图片的方法
2014/11/01 Javascript
浅谈javascript回调函数
2014/12/07 Javascript
JS实现同时搜索百度和必应的方法
2015/01/27 Javascript
纯css实现窗户玻璃雨滴逼真效果
2015/08/23 Javascript
jQuery添加options点击事件并传值实例代码
2016/05/18 Javascript
基于jQuery.validate及Bootstrap的tooltip开发气泡样式的表单校验组件思路详解
2016/07/18 Javascript
Angular2实现自定义双向绑定属性
2017/03/22 Javascript
React简单介绍
2017/05/24 Javascript
layui框架中layer父子页面交互的方法分析
2017/11/15 Javascript
AngularJS创建一个上传照片的指令实例代码
2018/02/24 Javascript
VUE+Element环境搭建与安装的方法步骤
2019/01/24 Javascript
微信小程序 数据缓存实现方法详解
2019/08/26 Javascript
2019年度web前端面试题总结(主要为Vue面试题)
2020/01/12 Javascript
[00:28]DOTA2北京网鱼队选拔赛
2015/04/08 DOTA
深入理解python多进程编程
2016/06/12 Python
39美元购买一副眼镜或太阳镜:39DollarGlasses.com
2018/06/17 全球购物
捷克移动配件网上商店:ProMobily.cz
2019/03/15 全球购物
小区停车场管理制度
2014/01/27 职场文书
2016年国庆节新闻稿范文
2015/11/25 职场文书
《月球之谜》教学反思
2016/02/20 职场文书
Java异常处理try catch的基本用法
2021/12/06 Java/Android