python学习笔记之八:迭代器和生成器
一. 迭代器
在前面的笔记中,已经提到过迭代器(和可迭代),这里会对此进行深入讨论。只讨论一个特殊方法---__iter__,这个方法是迭代器规则的基础。
1.1 迭代器规则
迭代的意思是重复做一些事情很多次,到现在为止只是在for循环中对序列和字典进行迭代,但实际上也能对其他的对象进行迭代:实现__iter__方法的对象。
__iter__方法返回一个迭代器,所谓迭代器就是具有next方法(这个方法在调用时不需要任何参数)的对象。在调用next方法时,迭代器会返回它的下一个值。如果next方法被调用,但迭代器没有值可以返回,就会引发一个StopIteration异常。
为什么不用列表?列表是一次性获取所有值的,如果有很多值,列表会占用太多的内存,但是迭代器可以在使用时计算一个值时获取一个值,使用迭代器更通用,简单,优雅。
下面来看一个不使用列表的例子:
__metaclass__ = type class Fibs:
def __init__(self):
self.a = 0
self.b = 0
def next(self):
self.a,self.b = self.b,self.a + self.b
return self.a
def __iter__(self):
return self
注意:迭代器实现了__iter__方法,这个方法实际上返回迭代器本身。很多情况下,__iter__会放到其他的会在for循环中使用的对象中。这样一来,程序就能返回所需的迭代器。此外,推荐使用迭代器实现它自己的_iter__方法,然后就能直接在for循环中使用迭代其本身了。
>>> f = Fibs()
>>> for n in f:
if n > 10:
print n
break 13
1.2 从迭代器得到序列
除了在迭代器和可迭代对象上进行迭代外,还能把它们转换为序列。在大部分能使用序列的情况下,能使用迭代器替换。关于这个的一个很有用的例子是使用list构造方法显式地将迭代器转化为列表。
__metaclass__ = type class TestIterator:
value = 0
def next(self):
self.value += 1
if self.value > 10:raise StopIteration
return self.value
def __iter__(self):
return self
>>> ti = TestIterator()
>>> list(ti)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
二. 生成器
生成器是python新引入的概念,由于历史原因,它也叫简单生成器。它和迭代器可能是近几年来引入的最强大的两个特性。生成器可以帮助读者写出非常优雅的代码。
生成器是一种用普通的函数语法定义的迭代器。让我们先看看怎么创建和使用生成器,然后再了解一下她的内部机制。
2.1 创建生成器
首先创建一个展开嵌套列表的函数,参数是一个列表的列表,类似于nested = [[1,2],[3,4],[5]],函数按照顺序打印出列表中的数字:
__metaclass__ = type def flatten(nested):
for sublist in nested:
for element in sublist:
yield element
这个函数首先迭代提供的嵌套列表中的所有子列表,然后按顺序迭代列表中的元素。yield语句是新知识,任何包含yield语句的函数都称为生成器。它不像return那样返回值,而是每次产生多个值。每次产生一个值,函数就会被冻结:即函数停在那点等待被激活,函数被激活后就从停止的那点开始执行。
接下来可以通过在生成器上迭代来使用所有的值:
>>> nested = [[1,2],[3,4],[5]]
>>> for num in flatten(nested):
print num 1
2
3
4
5
2.2 递归生成器
上面的例子中只能处理两层嵌套,如果不知道有多少层嵌套呢?我们就要求助于递归了:
__metaclass__ = type def flatten(nested):
try:
for sublist in nested:
for element in sublist:
yield element
except TypeError:
yield nested
当flatten被调用时,有两种可能性:基本情况和需要递归的情况,在特殊情况中,展开的是一个列表,程序必须遍历所有的字列表,并对他们调用flatten。然后用另一个for循环来产生被展开的子列表中的所有元素。
>>> nested = [[1,2],[3,4],[5,[6,[7]]]]
>>> for num in flatten(nested):
print num 1
2
3
4
5
[6, [7]]
(上面的结果跟书《python基础教程(第二版)》中例子的结果不一样,我也搞不懂)
python学习笔记之八:迭代器和生成器的更多相关文章
- python学习笔记四 迭代器,生成器,装饰器(基础篇)
迭代器 __iter__方法返回一个迭代器,它是具有__next__方法的对象.在调用__next__方法时,迭代器会返回它的下一个值,若__next__方法调用迭代器 没有值返回,就会引发一个Sto ...
- Python学习笔记010_迭代器_生成器
迭代器 迭代就类似于循环,每次重复的过程被称为迭代的过程,每次迭代的结果将被用来作为下一次迭代的初始值,提供迭代方法的容器被称为迭代器. 常见的迭代器有 (列表.元祖.字典.字符串.文件 等),通常 ...
- python学习笔记之迭代器和函数(第三天)
一.collection系列: 1.counter计数器 如果counter(dict)是对字典的一个补充,如果counter(list)则是对列表的补充,初步测试对字典的值进行排序. ####### ...
- python学习笔记(5)--迭代器,生成器,装饰器,常用模块,序列化
生成器 在Python中,一边循环一边计算的机制,称为生成器:generator. 如: >>> g = (x * x for xin range(10)) >>> ...
- python 3.x 学习笔记6 ( 迭代器 and 生成器 )
1.迭代器(Iterator): 可以被next()函数调用并不断返回下一个值的对象,成为迭代器:Iterator 可以直接用于for 循环的对象统称为可迭代对象:Iterable 迭代,顾名思 ...
- Python学习之路——迭代器、生成器、算法基础、正则
一.迭代器: 迭代器是访问集合元素的一种方式. 迭代器对象是从集合的第一个元素开始访问,直到所有的元素被访问完结束. 迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退. 另外,迭代 ...
- Python学习(三):迭代器、生成器、装饰器、递归、算法、正则
1.迭代器 迭代器是访问集合的一种方式,迭代对象从集合的第一个元素开始访问,直到元素被访问结束,迭代器只能往前不能后退,最大的优点是不要求事先准备好整个迭代过程中的元素,这个特点使得它特别适合用于遍历 ...
- python3学习笔记10(迭代器和生成器)
参考http://www.runoob.com/python3/python3-iterator-generator.html 迭代器 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束 ...
- Python学习笔记014——迭代器 Iterator
1 迭代器的定义 凡是能被next()函数调用并不断返回一个值的对象均称之为迭代器(Iterator) 2 迭代器的说明 Python中的Iterator对象表示的是一个数据流,被函数next()函数 ...
随机推荐
- BCB/Delphi中常用的VCL函数说明(文件函数)
--------------------文件操作--------------------函数名称:ChangeFileExt函数说明:更改指定文件的扩展名,函数原型如下:AnsiString __fa ...
- Could not find or load main class
Then add '.' to your $CLASSPATH with CLASSPATH=.:$CLASSPATH or as a paramater with java -classpath . ...
- Linux I/O 重定向详解及应用实例
Linux I/O 重定向详解及应用实例 简解 > 输出 < 输入 >> 追加 & [> | < | >>]之前:输入输出; ls /dev & ...
- hdu 5183(hash)
传送门:Negative and Positive (NP) 题意:给定一个数组(a0,a1,a2,⋯an−1)和一个整数K, 请来判断一下是否存在二元组(i,j)(0≤i≤j<n)使得 NP− ...
- 参数传递方法(Delphi1.0与win16API使用pascal方法,即从左到右)
参数传递方法李维的InsideVCL<第一章>中提到Windows定义的回调函数typedef LRESULT (CALLBACK*WNDPROC)(HWND,UNIT,WPARAM,LP ...
- table显示边框问题,隐藏行线,列线
只显示上边框 <table frame=above> 只显示下边框 <table frame=below> 只显示左.右边框 <table frame=vsides> ...
- 非对称加密RSA、Elgamal、背包算法、Rabin、D-H、ECC(椭圆曲线加密算法)等。使用最广泛的是RSA算法
非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey).公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密:如果用私 ...
- python语言学习2——安装python
python是跨平台的,可以,在各种操作系统上安装 window平台下安装python,安装步骤: 下载安装包 下载地址:https://www.python.org/ftp/python/3.5.0 ...
- hdu3605(最大流+状态压缩)
传送门:Escape 题意:给出每个人适合住的星球信息和该星球能住多少人 ,第一行给出n m 代表有 n 个人 m 个星球,然后接下来n行每行m个数字 1代表适合第 i 个星球 0 代表不适合第 i ...
- 那些年踩过的坑之:first-child伪类选择器
原文:那些年踩过的坑之:first-child伪类选择器 :first-child 选择器用于选取属于其父元素的首个子元素的指定选择器.——w3school 嗯,乍一看好像说的不是很明白,因此这个选择 ...