一. 迭代器

在前面的笔记中,已经提到过迭代器(和可迭代),这里会对此进行深入讨论。只讨论一个特殊方法---__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学习笔记之八:迭代器和生成器的更多相关文章

  1. python学习笔记四 迭代器,生成器,装饰器(基础篇)

    迭代器 __iter__方法返回一个迭代器,它是具有__next__方法的对象.在调用__next__方法时,迭代器会返回它的下一个值,若__next__方法调用迭代器 没有值返回,就会引发一个Sto ...

  2. Python学习笔记010_迭代器_生成器

     迭代器 迭代就类似于循环,每次重复的过程被称为迭代的过程,每次迭代的结果将被用来作为下一次迭代的初始值,提供迭代方法的容器被称为迭代器. 常见的迭代器有 (列表.元祖.字典.字符串.文件 等),通常 ...

  3. python学习笔记之迭代器和函数(第三天)

    一.collection系列: 1.counter计数器 如果counter(dict)是对字典的一个补充,如果counter(list)则是对列表的补充,初步测试对字典的值进行排序. ####### ...

  4. python学习笔记(5)--迭代器,生成器,装饰器,常用模块,序列化

    生成器 在Python中,一边循环一边计算的机制,称为生成器:generator. 如: >>> g = (x * x for xin range(10)) >>> ...

  5. python 3.x 学习笔记6 ( 迭代器 and 生成器 )

    1.迭代器(Iterator):   可以被next()函数调用并不断返回下一个值的对象,成为迭代器:Iterator  可以直接用于for 循环的对象统称为可迭代对象:Iterable 迭代,顾名思 ...

  6. Python学习之路——迭代器、生成器、算法基础、正则

    一.迭代器: 迭代器是访问集合元素的一种方式. 迭代器对象是从集合的第一个元素开始访问,直到所有的元素被访问完结束. 迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退. 另外,迭代 ...

  7. Python学习(三):迭代器、生成器、装饰器、递归、算法、正则

    1.迭代器 迭代器是访问集合的一种方式,迭代对象从集合的第一个元素开始访问,直到元素被访问结束,迭代器只能往前不能后退,最大的优点是不要求事先准备好整个迭代过程中的元素,这个特点使得它特别适合用于遍历 ...

  8. python3学习笔记10(迭代器和生成器)

    参考http://www.runoob.com/python3/python3-iterator-generator.html 迭代器 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束 ...

  9. Python学习笔记014——迭代器 Iterator

    1 迭代器的定义 凡是能被next()函数调用并不断返回一个值的对象均称之为迭代器(Iterator) 2 迭代器的说明 Python中的Iterator对象表示的是一个数据流,被函数next()函数 ...

随机推荐

  1. Java加入背景音乐

    近期有几个师妹找我给她们的Java期末作业加入背景音乐,非常久不琢磨Java的我花费整晚才搞定,羞愧.在博客中记录下来.警示自己.也帮助一下大家. Java中能够通过AudioClip类来实现音乐播放 ...

  2. alv 显示 汇总数据

    alv中有 字段设置 gs_fieldcat-do_sum = ‘1’.字段  用于控制汇总

  3. 与众不同 windows phone (4) - Launcher(启动器)

    原文:与众不同 windows phone (4) - Launcher(启动器) [索引页][源码下载] 与众不同 windows phone (4) - Launcher(启动器) 作者:weba ...

  4. jfinal常见问题

    2014年的时候,学过一段时间的JFinal,当时主要是了解这个框架,研究了下源码,看懂了部分.今天,2015年2月7日,弄了一下午的JFinal,把未来要上线的一个官网项目,迁移到了JFinal.下 ...

  5. JavaScript—DOM操作

  6. ASP.Net状态管理读书笔记--思维导图

    课前提问几个问题 使用Session 配置 model aspnet_regsql.exe 常见问答 问:为什么Session在有些机器上偶尔会丢失?答:可能和机器的环境有关系,比如:防火墙或者杀毒软 ...

  7. blender资源

    blender资源 只能发帖不能更改的百度贴吧贴. http://tieba.baidu.com/f?kw=blender blendercn youku视频专辑: http://i.youku.co ...

  8. Android开发经验之—intent传递大数据

    在Activity或者组件之前传递信息时,一般採用intent绑定bundle的方式传值,但在使用过程中须要注意的是不要用bundle传递大容量数据: 在做项目的过程中,须要将听写界面的听写结果信息传 ...

  9. codeforces 604A Uncowed Forces

    题目链接:http://codeforces.com/problemset/problem/604/A 题意:求cf比赛每次能够增加的排名,运算规则会告诉你 题目分类:数学 题目分析:用题目给的公式直 ...

  10. Codeforces 474 F. Ant colony

    线段树求某一段的GCD..... F. Ant colony time limit per test 1 second memory limit per test 256 megabytes inpu ...