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'))
浙公网安备 33010602011771号