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中的异常处理学习笔记
Jan 28 Python
Java中重定向输出流实现用文件记录程序日志
Jun 12 Python
Python用UUID库生成唯一ID的方法示例
Dec 15 Python
Python3.4编程实现简单抓取爬虫功能示例
Sep 14 Python
详解python里使用正则表达式的全匹配功能
Oct 19 Python
numpy中索引和切片详解
Dec 15 Python
python的socket编程入门
Jan 29 Python
Python3如何对urllib和urllib2进行重构
Nov 25 Python
Python3.5 win10环境下导入kera/tensorflow报错的解决方法
Dec 19 Python
python实现电子词典
Mar 03 Python
Python CSS选择器爬取京东网商品信息过程解析
Jun 01 Python
Keras load_model 导入错误的解决方式
Jun 09 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
Notice: Trying to get property of non-object problem(PHP)解决办法
2012/03/11 PHP
php 魔术方法详解
2014/11/11 PHP
ThinkPHP模版中导入CSS和JS文件的方法
2014/11/29 PHP
解决PHP 7编译安装错误:cannot stat ‘phar.phar’: No such file or directory
2017/02/25 PHP
PHP巧妙利用位运算实现网站权限管理的方法
2017/03/12 PHP
js控制框架刷新
2008/08/01 Javascript
传智播客学习之java 反射
2009/11/22 Javascript
jquery的ajax从纯真网(cz88.net)获取IP地址对应地区名
2009/12/02 Javascript
JQuery对checkbox操作 (循环获取)
2011/05/20 Javascript
javascript五图轮播切换实用版
2012/08/17 Javascript
jQuery操作Select选择的Text和Value(获取/设置/添加/删除)
2013/03/06 Javascript
jQuery探测位置的提示弹窗(toolTip box)详细解析
2013/11/14 Javascript
jquery mobile动态添加元素之后不能正确渲染解决方法说明
2014/03/05 Javascript
JavaScript函数的一些注意要点小结及js匿名函数
2015/11/10 Javascript
BootStrap table表格插件自适应固定表头(超好用)
2016/08/24 Javascript
Kindeditor单独调用单图上传增加预览功能的实例
2017/07/31 Javascript
AngularJs 禁止模板缓存的方法
2017/11/28 Javascript
微信小程序button组件使用详解
2018/01/31 Javascript
从Vuex中取出数组赋值给新的数组,新数组push时报错的解决方法
2018/09/18 Javascript
微信小程序如何修改本地缓存key中单个数据的详解
2019/04/26 Javascript
vue中实现拖动调整左右两侧div的宽度的示例代码
2020/07/22 Javascript
Python logging模块学习笔记
2014/05/24 Python
编写Python脚本使得web页面上的代码高亮显示
2015/04/24 Python
详解Swift中属性的声明与作用
2016/06/30 Python
python实现可视化动态CPU性能监控
2018/06/21 Python
python3+selenium自动化测试框架详解
2019/03/17 Python
python实现AES加密和解密
2019/03/27 Python
基于python traceback实现异常的获取与处理
2019/12/13 Python
Django def clean()函数对表单中的数据进行验证操作
2020/07/09 Python
Mybag美国/加拿大:英国奢华包包和名牌手袋网站
2020/02/16 全球购物
酒店总经理工作职责
2013/12/13 职场文书
爱岗敬业演讲稿范文
2014/01/14 职场文书
教学督导岗位职责
2015/04/10 职场文书
2015年实习班主任工作总结
2015/04/23 职场文书
拿破仑传读书笔记
2015/07/01 职场文书
Python 如何实现文件自动去重
2021/06/02 Python