设计 Iterator 接口时考虑到了惰性:next(my_iterator) 一次生成一个元素。懒惰的反义 词是急迫,其实,惰性求值(lazy evaluation)和及早求值(eager evaluation)是编程语言 理论方面的技术术语。

目前之前博客的几版 Sentence 类都不具有惰性,因为 __init__ 方法急迫地构建好了文本中的 单词列表,然后将其绑定到 self.words 属性上。这样就得处理整个文本,列表使用的内存 量可能与文本本身一样多(或许更多,这取决于文本中有多少非单词字符)。如果只需迭代前几个单词,大多数工作都是白费力气。

只要使用的是 Python 3,思索着做某件事有没有懒惰的方式,答案通常都是肯定的,惰性实现才更符合python语言的规范。

re.finditer 函数是 re.findall 函数的惰性版本,返回的不是列表,而是一个生成器,按 需生成 re.MatchObject 实例。如果有很多匹配,re.finditer 函数能节省大量内存。我们 要使用这个函数让 Sentence 类变得懒惰,即只在需要时才生成下一个单词。

示例:

import re
import reprlibRE_WORD = re.compile('\w+')class Sentence:def __init__(self, text):self.text = textdef __repr__(self):# reprlib.repr 这个实用函数用于生成大型数据结构的简略字符串表示形式return 'Sentence(%s)' % reprlib.repr(self.text)def __iter__(self):# 迭代 self.wordsfor match in RE_WORD.finditer(self.text):yield match.group()if __name__ == '__main__':s = Sentence('I love python')ss = iter(s)print(ss)print(next(ss))print(next(ss))print(next(ss))print(list(ss))

生成器函数已经极大地简化了代码,但是使用生成器表达式甚至能把代码变得更简短。

简单的生成器函数,如前面的 Sentence 类中使用的那个,可以替换成生成 器表达式。

生成器表达式可以理解为列表推导的惰性版本:不会迫切地构建列表,而是返回一个生成 器,按需惰性生成元素。也就是说,如果列表推导是制造列表的工厂,那么生成器表达式 就是制造生成器的工厂,其实就是将列表推到中的[]换成(),就行了。

import re
import reprlibRE_WORD = re.compile('\w+')class Sentence:def __init__(self, text):self.text = textdef __repr__(self):# reprlib.repr 这个实用函数用于生成大型数据结构的简略字符串表示形式return 'Sentence(%s)' % reprlib.repr(self.text)def __iter__(self):# 迭代 self.words# for match in RE_WORD.finditer(self.text):#     yield match.group()return (match.group() for match in RE_WORD.finditer(self.text))if __name__ == '__main__':s = Sentence('I love python')ss = iter(s)print(ss)print(next(ss))print(next(ss))print(next(ss))print(list(ss))

唯一的区别是 __iter__ 方法,这里不是生成器函数了(没有 yield),而是使 用生成器表达式构建生成器,然后将其返回。不过,最终的效果一样:调用 __iter__ 方法 会得到一个生成器对象。

生成器表达式语法糖:完全可以替换成生成器函数,不过有时使用生成器表达式更便利。

python 中惰性实现相关推荐

  1. python中and和or的惰性求值特点_惰性求值和yield-Python

    惰性求值 惰性求值(Lazy evaluation)是在需要时才进行求值的计算方式.表达式不在它被绑定到变量之后就立即求值,而是在该值被取用的时候求值. 除可以得到性能的提升(更小的内存占用)外,惰性 ...

  2. python中and和or的惰性求值特点_python中的惰性求值

    可能经常会有人问到python中的range和xrange有什么区别,你知道range是直接创建了一个列表,而xrange是创建了一个生成器,并且xrange非常适合当需要创建一个很大的列表的时候,因 ...

  3. python中and和or的惰性求值特点_Python 惰性求值

    Python 惰性求值,函数式编程高效,原因之一是将计算推迟到需要的时候进行.惰性(也称"非严格")求值非常重要,Python内置了对它的支持. Python中,逻辑运算符and. ...

  4. python 惰性属性_python中惰性对象

    惰性对象是什么? 首先需要明确啥是惰性计算(lazy evaluation):是指仅仅在真正需要执行的时候才计算的表达式的值.充分利用其特点 可以带来很多的便利 1. 避免不必要的计算,带来性能的提升 ...

  5. 什么是python中的惰性评估

    If you've never heard of Lazy Evaluation before, Lazy Evaluation is an evaluation strategy which del ...

  6. python中生成器的惰性机制

    生成器有一个惰性机制,只有当你需要的时候才给你(一个个的取),而不是一下字全部给你.可能有些抽象,来一个例子 吧. 普及一个小知识**:一只母鸡并不是生一辈子鸡蛋,有一个时间段.** 例:小明和小红两 ...

  7. python yield 惰性计算,用于scrapy中(美食杰爬虫为例)

    先说一下什么是python的惰性计算 惰性计算(Lazy evaluation)是指仅仅在真正需要执行的时候才计算表达式的值.充分利用其特性可以带来很多便利.yield的功能类似于return,但是不 ...

  8. Python中正则表达式用法 重点格式以这个为准_首看_各种问题

    20210811 https://www.jb51.net/article/101258.htm 一.惰性模式的概念: 此模式和贪婪模式恰好相反,它尽可能少的匹配字符以满足正则表达式即可,例如: va ...

  9. pythonfor循环遍历list_为什么for循环可以遍历list:Python中迭代器与生成器

    1 引言 只要你学了Python语言,就不会不知道for循环,也肯定用for循环来遍历一个列表(list),那为什么for循环可以遍历list,而不能遍历int类型对象呢?怎么让一个自定义的对象可遍历 ...

最新文章

  1. 无人驾驶汽车系统入门:基于VoxelNet的激光雷达点云车辆检测及ROS实现
  2. 今日头条CEO朱文佳:新一代搜索引擎已经来了
  3. HDU - 3068 最长回文(manacher)
  4. 获取android系统手机的铃声和音量
  5. Palindromic Twist(CF-1027A)
  6. 【TSP】基于matlab遗传算法求解30城市旅行商问题【含Matlab源码 135期】
  7. 神策分析 iOS SDK 全埋点解析之启动与退出 | 数据采集
  8. 家用NAS有什么用?充分挖掘你的NAS功能
  9. Relay和Rendezvous
  10. POSCMS 后台安全
  11. 不忘历史、维护中国海权
  12. LAMMPS模拟in和data文件集合
  13. C++练习小写变大写
  14. iphone照片恢复至android,将照片从Android传输到iPhone的8种方法很容易
  15. 上海调高公积金贷款上限 首次购房每户可贷50万
  16. RandomResizedCrop
  17. 微信小程序弹窗滚动导致页面穿透问题的解决办法
  18. 最新养鱼源码-支持商城抽奖,余额宝等,支持中英文,带安装教程
  19. iOS之Xcode断点调试
  20. linux 4g网卡路由,openwrt编译加载龙尚U8300 4G网卡

热门文章

  1. bitcomet端口阻塞,黄灯,解决方案
  2. python_day05(笔记及练习)
  3. H5生成字体图标方法
  4. 使用Python自动给视频逐帧截图
  5. 2018俄罗斯世界杯 模拟抽签结果 (PHP版)
  6. 派学车融资、YY学车倒闭,互联网驾培旱涝两重天
  7. 删除鼠标右键Office 的共享文件夹同步 已成功
  8. 微博相互关注互粉mysql表实现
  9. Webpack优化——将你的构建效率提速翻倍
  10. 2010-2013年中国第三方支付行业研究报告