python学习10—迭代器、三元表达式与生成器
1. 迭代器协议
定义:对象必须提供一个next方法,执行该方法或者返回迭代中的下一项,或者返回一个StopIteration异常,以终止迭代(只能往后走不能往前退)
2. 可迭代对象
实现了迭代器协议的对象,对象内部定义一个__iter__()方法
3. for循环实现机制
字符串、列表,元组,字典,集合,文件等都不具有next方法,所以他们都不是可迭代对象(iterable object),但是为什么for循环可以进行呢?
原因:for循环首先调用了他们的内置方法__iter()__方法将其转换为可迭代对象,然后再调用这个转换后的可迭代对象的__next()__方法,进行迭代。
l = [1,2,3] # iterable object iter_l = l.__iter__() print(iter_l.__next__())
字符串、列表、元组为有序序列,也可以通过索引取值,但是字典、集合、文件等非序列类型,不可以通过索引取值,所以出现了for循环,一个基于迭代器协议的统一的遍历方式。
4. 使用while循环实现for循环机制
l = [1,2,3]
detail_l=l.__iter__() while True: try: print(detail_l.__next__()) except StopIteration: print('end of iteration') break
5. next()函数
python内置函数next()调用对象的__next()__方法,实现机制与__next()__相同。
l = [1,2,3,5,6] l_iter = l.__iter__() print(l_iter.__next__()) #两行print()代码效果相同 print(next(l_iter))
6. 三元表达式
如下代码,如果name == 'b'则返回a,如果name不等于'b'则返回c。
name = 'b' result = 'a' if name == 'b' else 'c'
相当于c++中的条件运算符(三目运算符)“?:”,都是对一个条件进行判断,满足条件与否分别返回一个值。
#include<iostream> using namespace std; int main() { int a = 4; int b = 5; int c = a>b ? a : b; return 0; }
7. 列表解析
利用三元表达式可以进行列表解析。
egg = ['egg %s' %i for i in range(10) if i > 2]
返回:
>>> ['egg 3', 'egg 4', 'egg 5', 'egg 6', 'egg 7', 'egg 8', 'egg 9']
8. 生成器
生成器作为一种数据类型,自动实现了迭代器协议,即可以直接调用生成器的__next__()方法,生成器就是可迭代对象。
8.1 生成器函数
生成器函数使用yield代替return,且可返回多个值,每次调用返回一个值。
def f(): yield 1 yield 2 yield 3 yield 4 yield 5 iter_f = f() print(iter_f.__next__()) print(iter_f.__next__()) print(iter_f.__next__())
8.2 生成器表达式
将列表解析的[]替换为()即可获得生成器表达式。
egger = ('egg %s' %i for i in range(10) if i > 2) print(egger) print(egger.__next__()) print(egger.__next__()) print(egger.__next__())
很多python内置函数如sum(),map(),reduce(),filter()等都是遵循迭代器协议的,故可利用生成器进行一些高级的操作。
sum(x**2 for x in range(10))
注意:生成器只能遍历一次,遍历之后,生成器被释放。