从零开始的Python学习Episode 12——迭代器&生成器
生成器
列表生成式
用于快速地生成一个列表
a = [x*x for x in range(1,9)]
print(a) #输出[1, 4, 9, 16, 25, 36, 49, 64]
也可以用于生成函数结果的列表
def f(n):
return n**3 a = [f(x) for x in range(1,9)]
print(a) #输出[1, 8, 27, 64, 125, 216, 343, 512]
迭代器
迭代器是一个带状态的对象,他能在你调用 next() 方法的时候返回容器中的下一个值,任何实现了 __next__()方法的对象都是迭代器。
拿斐波拉契数列作例子
def fib(max):
L = []
n, a, b = 0, 0, 1
while n < max:
L.append(b)
a, b = b, a + b
n = n + 1
return L
这种用法会如果max的很大的话会占用特别多的内存,导致程序卡顿。
使用迭代器可以解决复用可占空间的问题
迭代器可以通过 next() 不断返回数列的下一个数,内存占用始终为常数。
class Fib(object):
def __init__(self, max):
self.max = max
self.n, self.a, self.b = 0, 0, 1 def __iter__(self):
return self def next(self):
if self.n < self.max:
r = self.b
self.a, self.b = self.b, self.a + self.b
self.n = self.n + 1
return r
raise StopIteration()
生成器
生成器其实是一种特殊的迭代器。生成器(yield)既可以保持代码的简洁性,又可以减少占用内存的效果。它不需要再像上面的类一样写 __iter__() 和 __next__() 方法了,只需要一个 yiled 关键字。
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1 for n in fib(5):
print(n) #输出
1
1
2
3
5
yield 的作用就是把一个函数变成一个生成器,带有 yield 的函数不再是一个普通函数,Python 解释器会将其视为一个生成器,在 for 循环执行时,每次循环都会执行 fib 函数内部的代码,执行到 yield b 时,fib 函数就返回一个迭代值,下次迭代时,代码从 yield b 的下一条语句继续执行,而函数的本地变量看起来和上次中断执行前是完全一样的,于是函数继续执行,直到再次遇到 yield。看起来就好像一个函数在正常执行的过程中被 yield 中断了数次,每次中断都会通过 yield 返回当前的迭代值。
(1)send()方法
send方法可以往生成器里传值
def f():
print("ok")
n = yield
print(n)
print("ok2")
yield 2
f = f()
f.send(None)
f.send(1)
next(f)
#输出
ok
Traceback (most recent call last):
1
ok2
File "D:/PyCharm Project/test/Starter/test2.py", line 10, in <module>
next(f)
StopIteration
send方法会把值传到yield前的对象,并往下执行到下一个yield。但当使用send之前要先用next或者用send(None)来获取yield的位置,否则无法把值传给yield。
还有一点:
在一个生成器中,如果没有return,则默认执行到函数完毕;如果遇到return,如果在执行过程中 return,则直接抛出 StopIteration 终止迭代。而for不报错的原因是内部处理了迭代结束的这种情况。
是一个带状态的对象,他能在你调用 next() 方法的时候返回容器中的下一个值,任何实现了 __next__() (python2中实现 next() )方法的对象都是迭代器
从零开始的Python学习Episode 12——迭代器&生成器的更多相关文章
- Python学习---装饰器/迭代器/生成器的学习【all】
Python学习---装饰器的学习1210 Python学习---生成器的学习1210 Python学习---迭代器学习1210
- python学习笔记(5)--迭代器,生成器,装饰器,常用模块,序列化
生成器 在Python中,一边循环一边计算的机制,称为生成器:generator. 如: >>> g = (x * x for xin range(10)) >>> ...
- 从零开始的Python学习Episode 15——正则表达式
正则表达式 正则表达式(或 RE)是一种小型的.高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现,所以使用时要导入re模块.正则表达式模式被编译成一系列的字节码 ...
- 从零开始的Python学习Episode 13——常用模块
模块 一.time模块 时间戳(timestamp) :时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量. 元组(struct_time) :struct_time元组共有9 ...
- 从零开始的Python学习Episode 23——进程
---恢复内容开始--- 进程 由于GIL的存在,python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程.Python提供了非常好用 ...
- 从零开始的Python学习Episode 22——多线程
多线程 线程 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务. ...
- 从零开始的Python学习Episode 21——socket基础
socket基础 网络通信要素: A:IP地址 (1) 用来标识网络上一台独立的主机 (2) IP地址 = 网络地址 + 主机地址(网络号:用于识别主机所在的网络/网段.主机号:用于识别该网络中的 ...
- 从零开始的Python学习Episode 20——面向对象(3)
面向对象之封装 封装,即隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别:将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体. 隐藏 在python中用双下划线开 ...
- 从零开始的Python学习Episode 19——面向对象(2)
面向对象之继承 继承是一种创建新类的方式,新建的类可以继承一个或多个父类(python支持多继承),父类又可称 为基类或超类,新建的类称为派生类或子类. 子类会“”遗传”父类的属性,从而解决代码重用问 ...
随机推荐
- #ifdef 和 #if defined的区别
#ifdef 和 #if defined的区别在于,后者可以组成复杂的预编译条件,比如 #if defined (AAA) && defined (BBB)xxxxxxxxx#endi ...
- 大话Linux内核中锁机制之完成量、互斥量
大话Linux内核中锁机制之完成量.互斥量 在上一篇博文中笔者分析了关于信号量.读写信号量的使用及源码实现,接下来本篇博文将讨论有关完成量和互斥量的使用和一些经典问题. 八.完成量 下面讨论完成量的内 ...
- 直接在apk中添加资源的研究
原文 http://blog.votzone.com/2018/05/12/apk-merge.html 之前接手过一个sdk的开发工作,在开发过程中有一个很重要的点就是尽量使用代码来创建控件,资源文 ...
- 位图索引对于DML操作的影响
位图索引相对于常规的B-tree 索引,有着体积更加小的优势,节省空间.对于重复率特别高的字段,比如性别,比如省份.查询效率要优于B-tree 索引.那为什么我们总被告知在业务库中不要使用呢? 业务库 ...
- 在express中HMR(合并express和webpack-dev-server)
在学习react的时候,经常用create-react-app来创建web应用,然而写到后面总有连自己服务器和数据库的需求,create-react-app创建的是一个webpack-dev-serv ...
- 20181031noip模拟赛T2
思路: 这道题是个图论抽象的题目…… 考场上想到了没写对…… 我们发现,f函数转移的方式有两种,要么是代价10的+1,要么是代价1的乘一个质因数 那么我们就可以将这个抽象为一张图 每个i向每个i+1连 ...
- ionic ios 打包 真机测试常见问题
1.ionic 项目在windows下正常打包安卓包时 迁移到mac下打包ios时 不需要复制平台目录platforms即可 不用再mac下去安装各种插件信息 2.ionic 下不能访问api信 ...
- svg图标(svg实现的QQ图标)
与传统的图片相比,用svg实现的图标要更好控制. 比如.若要改变图标的颜色,如果用图片的话,就需要UI设计人员调整图片,而如果用svg的话,就不用那么麻烦,开发人员改样式就行了. 附一个svg实现的Q ...
- 虚拟机VMware安装linux无法上网解决办法
虚拟机VMware安装linux无法上网解决办法 Linux网络设置: 依次单击[System]-->[Preferences]-->[Network Connections],如下图 ...
- Python学习 :多线程 --- 锁
多线程 什么是锁? - 锁通常被用来实现对共享资源的同步访问. - 为每一个共享资源创建一个Lock对象,当你需要访问该资源时,调用acquire方法来获取锁对象(如果其它线程已经获得了该锁,则当前线 ...