活下去通常不难,活得精彩永远很难。得过不且过,这是一种精神。

【python核心编程读书笔记】第8章--条件和循环

Posted on 2012-04-02 19:37  second  阅读(251)  评论(0)    收藏  举报

8.11迭代器与iter()函数

python与stl的迭代器比较相似。迭代器有这样的好处:1.提供可扩展的迭代器接口。2.对列表迭代带来了性能上的增强。3.在字典迭代中性能提升。4.提供更好的兼容性。5.增强代码的简洁性。

如何迭代
根本上说,迭代器就是有一个next()方法的对象,带迭代结束时,应抛出一个StopIteration异常来告诉外部调用者迭代完成。 

使用迭代器应该注意到,不能向后移动,不能回到开头,也不能复制迭代器,而且,迭代过程中改变被迭代对象会使迭代器失效(可对照stl相关内容理解)

对一个对象使用iter()函数就可以得到该对象的迭代器。它的语法如下: 
iter(obj)
iter(func, sentinel ) 


如果你传递一个参数给 iter() , 它会检查你传递的是不是一个序列, 如果是, 那么很简单: 根据索引从 0 一直迭代到序列结束. 另一个创建迭代器的方法是使用类, 我们将在第 13 章详细介绍, 一个实现了 __iter__() 和 next() 方法的类可以作为迭代器使用. 

如果是传递两个参数给 iter() , 它会重复地调用 func , 直到迭代器的下个值等于 sentinel . 

8.12列表解析

之前介绍列表的时候已经提及列表解析。语法如下:

[expr for iter_var in iterable if cond_expr]   for语句可以有多条。 

你需要迭代一个有三行五列的矩阵么? 很简单:

>>> [(x+1,y+1) for x in range(3) for y in range(5)]
[(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (2, 1), (2, 2), (2,
3), (2, 4), (2, 5), (3, 1), (3, 2), (3, 3), (3, 4), (3, 5)]  

 8.13生成器表达式

列表解析是很方便,而且可以使代码更简洁,但有一个问题,当需要解析的列表数据量很大时,就需要占用大量的内存,这样会在性能上带来负面影响。

那么我们需要一个可以避免上面问题的“列表解析”。首先,我们需要明白列表解析为什么存在上面的问题。简单来说,列表解析是一个“过度热情”设计,即使是暂时不用的值也被创建出来,那么,如果延迟列表值的产生就可以解决上述问题了。

在python里,生成器就是一个“懒惰的列表解析”。生成器和map()的使用非常相似。每生产一个值,就交给上层使用一次,而且,生成器的语法与列表解释非常相似。于是乎,使用生成器就可以同时实现使用简洁代码而又不占过多内存了。

生成器表达式语法:
(expr for iter_var in iterable if cond_expr) 

栗子 :得到一个文件中最长的一行

max(len(x.strip()) for x in open('/etc/motd'))