十二. Python基础(12)--生成器
十二. Python基础(12)--生成器
1 ● 可迭代对象(iterable)
|
An object capable of returning its members one at a time. Examples of iterables include all sequence types (such as list, str, and tuple) and some non-sequence types like dict and file and objects of any classes you define with an __iter__() or __getitem__() method. An iterable object works as the source of items in for loops, comprehensions and tuple unpacking. Iterables are objects that produce an iterator when they are passed to the iter() builtin. |
|
一些iterable将所有值都存储在内存中,比如list,而另一些并不是这样,比如我们下面将讲到的iterator. |
|
Python内置的可迭代对象: range(),str,list,tuple,dict,set |
2 ● 迭代器(iterator)
|
An object representing a stream of data. Repeated calls to the iterator's __next__ () method return successive items in the stream. When no more data are available a StopIteration exception is raised instead. Also, Iterators are required to have an __iter__() method that returns the iterator object itself (返回迭代器对象自身), so every iterator is also iterable. ※ |
|
python的迭代器为什么一定要实现__iter__方法? iterator实现(implement)的__iter__是为了兼容iterable的接口,从而让iterator成为iterable的一种实现. |
|
Python内置的迭代器: iter(range()),iter(str),iter(list),iter(tuple),iter(dict),iter(set),reversed(list_o),map(func,list_o),filter(func,list_o),file_o |
3 ● 判断是否为可迭代对象/迭代器
|
from collections import Iterable print(isinstance('aaa', Iterable)) # True print(isinstance('aaa'.__iter__(), Iterable)) # True, Iterator属于Iterable |
|
from collections import Iterator print(isinstance([1,2,3], Iterator)) # False print(isinstance([1,2,3].__iter__(), Iterator)) #True |
4 ● 可迭代对象协议(iterable protocol)/迭代器协议(iterator protocol)
|
可迭代对象协议: 对象内部实现了__iter__方法。 ※ |
|
迭代器协议: 对象内部实现了__iter__()方法和__next__()方法. ※ |
|
__iter__()方法: 返回一个迭代器对象 __next__()方法: 返回迭代器的下一个项目 |
5● 迭代器的表象&本质
|
表象: Python从迭代器中一个一个的取值. |
|
本质:把标志控制的循环 |
6 ● 生成器(generator)&生成器函数(generator function)&生成器表达式(generator expression)
|
generator: (自己实现的iterator) Both generator functions and generator expressions are generators, by which we can build an iterator by ourseleves. 迭代器就是我们自己就可以通过生成器函数和生成器表达式实现的迭代器. 生成器一定是迭代器, 但迭代器不一定是生成器.
※ 生成器的特点(同样适用于迭代器): ① 节省内存(因为惰性计算): iterate through potentially huge sequences without creating and storing the entire sequence in memory at once. ② 一个生成器只能运行一次: 生成器中的每个值只能按顺序取一次, 并且不能返回取值, 取完后就不能再从生成器中取值了; ③ 惰性运算: 生成器只有在被调用的时候才会生成相应的数据(用__next__()、 for、list调用, 或被其它函数调用), 反之就不会生成--因此python适合大数据处理 ④ 无法复制一个生成器 (无论是直接复制给另一个对象, 还是进行深浅拷贝, 都不能复制生成器, 因此要再次进行迭代只能重新生成一个新的迭代器对象) ※⑤ 可以把非线性化的处理转换成线性化的方式来进行处理。 |
|
迭代器函数(generator function): A function that has the yield keyword in its body. 1. 概念:带yield关键字的函数就是生成器函数 2. 特点(也是迭代器的特点, 见上): 3. 从生成器中取值的方法: ①__next__() 有几个yield就可以取几次 ② for循环取值 ③用其他数据类型进行强制转换, 例如, list(g)返回一个列表, 里面装着生成器中的所有内容 ※ |
|
迭代器表达式/迭代器推导式(generator expression/generator comprehension): An expression enclosed in parenthesis using the same syntax of a list comprehension, but returning a generator instead of a list. A generator expression can be understood as a lazy version of a list comprehension. |
7 ● 几个概念的关系
|
※ A generator is a subtype of iterator; an iterator is an iterable. ※ ※
|
8 ● 生成迭代器的两种方法
|
# 使用对象内置的__iter__()方法生成迭代器 L1 = [1,2,3] I1 = L1.__iter__() print(I1) print(I1.__next__()) #1, python2还可以写成print I1.next(), python3还可以写成print(next(I1)) print(I1.__next__()) # 下面是容错处理: while True: try: print(I1.__next__()) except StopIteration: break |
|
# 使用内置工厂函数生成迭代器 L1 = [1,2,3] I2 = iter(L1) print(I2) print(I2.next()) # 1, 在python3中, 会提示没有next()这个方法,只能用__next__()或next(iterator) print(I2.next()) |
9 ● for和可迭代对象和迭代器
|
for loop可作用于(work on)可迭代对象和迭代器. for循环的本质: ① 循环不是迭代器的可迭代对象 ② 循环迭代器:直接调用迭代器的__next__()方法 |
|
import time start_time_1 = time.time() for i in range(200000000): pass time_cost_1 = time.time() - start_time_1 print('time_cost_1:',time_cost_1)
time.sleep(5)
import time start_time_2 = time.time() for i in range(200000000).__iter__(): pass time_cost_2 = time.time() - start_time_2 print('time_cost_2:',time_cost_2) |
|
time_cost_1: 21.656238555908203 time_cost_2: 24.198384284973145 # 迭代器可以节省内存, 但速度不一定快. |
10 ● 生成器表达式的案例
|
number_thing = (number for number in range(1, 6)) 圆括号之间的是生成器推导式(generator comprehension),它返回的是一个生成器对象(generator object): >>> type(number_thing) <class 'generotor'> 你可以直接对生成器对象进行迭代,如下所示: >>> for number in number_thing: ... print(number) ... 1 2 3 4 5 或者通过调用list() 函数: >>> number_list = list(number_thing) >>> number_list [1, 2, 3, 4, 5] |
|
※ A generator can be run only once. Lists, sets, strings, and dictionaries exist in memory, but a generator creates its values on the fly(即时, 立刻, 马上) and hands them out one at a time through an iterator. It doesn't remember them, so you can't restart or back up a generator. 一个生成器只能运行一次。列表、集合、字符串和字典都存储在内存中,但是生成器仅在运行中产生值,不会被存下来,所以不能重新使用或者备份一个生成器。 例如: >>> try_again = list(number_thing) >>> try_again |
11 ● eager and lazy(急切和懒惰)
|
An iterable object that builds all its items at once. In Python, a list comprehension is eager. Contrast with lazy. |
|
An iterable object which produces items on demand. In Python, generators are lazy. Contrast with eager. |
12 ● 生成器最相关的面试题
|
① 生成器中的内容需要使用__next__()、 for、list主动获取才会生成, 反之就不会生成--惰性运算 ② 使用__next__()、for、list从迭代器中取值后, 迭代器中的内容必然会减少或者完全用光. |
13 ● 监听文件输入的内容
|
import time def tail(filename): f = open(filename, encoding= "utf-8") f.seek(0,2) while True: line = f.readline() if not line: time.sleep(0.1) # 避免因为while True的原因导致内存消耗过大, continue else: yield line
tail_gen = tail("test.txt") for line in tail_gen: print(line, end = "") |
十二. Python基础(12)--生成器的更多相关文章
- 二十二. Python基础(22)--继承
二十二. Python基础(22)--继承 ● 知识框架 ● 继承关系中self的指向 当一个对象调用一个方法时,这个方法的self形参会指向这个对象 class A: def get(s ...
- 二十六. Python基础(26)--类的内置特殊属性和方法
二十六. Python基础(26)--类的内置特殊属性和方法 ● 知识框架 ● 类的内置方法/魔法方法案例1: 单例设计模式 # 类的魔法方法 # 案例1: 单例设计模式 class Teacher: ...
- 二十五. Python基础(25)--模块和包
二十五. Python基础(25)--模块和包 ● 知识框架 ● 模块的属性__name__ # my_module.py def fun1(): print("Hello& ...
- 二十四. Python基础(24)--封装
二十四. Python基础(24)--封装 ● 知识结构 ● 类属性和__slots__属性 class Student(object): grade = 3 # 也可以写在__slots ...
- 十八. Python基础(18)常用模块
十八. Python基础(18)常用模块 1 ● 常用模块及其用途 collections模块: 一些扩展的数据类型→Counter, deque, defaultdict, namedtuple, ...
- 十六. Python基础(16)--内置函数-2
十六. Python基础(16)--内置函数-2 1 ● 内置函数format() Convert a value to a "formatted" representation. ...
- 『Python基础-12』各种推导式(列表推导式、字典推导式、集合推导式)
# 『Python基础-12』各种推导式(列表推导式.字典推导式.集合推导式) 推导式comprehensions(又称解析式),是Python的一种独有特性.推导式是可以从一个数据序列构建另一个新的 ...
- 二. Python基础(2)--语法
二. Python基础(2)--语法 1.实现一个简单的登录系统 '''# 形式1 n = 1 while n < 4: name = input("请输入姓名\n" ...
- Tensorflow深度学习之十二:基础图像处理之二
Tensorflow深度学习之十二:基础图像处理之二 from:https://blog.csdn.net/davincil/article/details/76598474 首先放出原始图像: ...
随机推荐
- python中进程间通讯——文件锁之fcntl模块的使用
python 中给文件加锁——fcntl模块import fcntl 打开一个文件##当前目录下test文件要先存在,如果不存在会报错.或者以写的方式打开f = open('./test')对该文件加 ...
- 日常英语---四、vis.js是什么
日常英语---四.vis.js是什么 一.总结 一句话总结:A dynamic, browser based visualization library. 动态基于浏览器的可视库 http://vis ...
- Go语言学习之7 接口实例、终端文件读写、异常处理
本节主要内容: 1. 终端读写2. 文件读写3. 命令行参数4. Json5. 自定义错误 1. 终端读写 操作终端相关文件句柄常量 os.Stdin:标准输入 os.Stdout:标准输 ...
- WmiPrvSe.exe 的 cpu 占用
经常会看到这个进程cpu升上去,然后播放视频卡顿,鼠标移动卡顿. 1) 首先怀疑公司的Mcafee, 然后竟然检索除了一篇文章,MCafee表示不背锅. 2)找到这篇文章,微软表示,不能看表面,你得查 ...
- Windows Live Wirter
安装: 下载: Windows Live Writer (QQ 里) windows live writer 日志服务器发生问题 更新账户信息 从字面"editPost"我们不难看 ...
- ubuntu vi配置
1.先卸载tiny版本vi 输入命令:sudo apt-get remove vim-common 2.然后再输入命令: sudo apt-get install vim sudo vim /et ...
- memtrack: Couldn't load memtrack module (No such file or directory) 的问题解决
通过了编译,可是在模拟器运行时,却出现stopping…….查看logcat,发现出现错误: E/memtrack: Couldn't load memtrack module (No such fi ...
- php文件包含漏洞(利用phpinfo)复现
利用docker复现该漏洞,访问http://192.168.80.156:8080/phpinfo.php,可以看到页面出现phpinfo页面 再访问http://192.168.80.156:8 ...
- tomcat压缩版配置
下载Jdk并安装 配置Java环境变量 因为需要用services.bat安装,services.bat中 rem Make sure prerequisite environment variabl ...
- 如何使a标签打开新页面并阻止刷新当前页面
错误: HTML中,使用href属性时,当前页面和新页面均跳转到URL指定的页面,即当前页面也刷新: <li id='goToBack'><a href='**.action' ta ...
