复习一下python的高级特性
可迭代对象
当需要迭代一个对象时, 会自动调用iter
函数, iter
函数会检查对象是否实现了__iter__
方法, 如果有则调用对象的__iter__
方法获取一个迭代器, 没有则继续检查对象
是否实现了__getitem__
方法, 如果有, python会自动创建一个迭代器, 使用从0开始的索引
为参数调用__getitem__
, 该方法将返回对应索引的元素, 如果__getitem__
方法也不存
在, 则抛出TypeError
异常, 提示对象不可迭代
可迭代对象(iterable)就是使用内置函数iter
可以获取迭代器的对象, 该对象要么实现了能
够直接返回迭代器的__iter__
方法, 要么实现了接受从0开始的索引为参数的__getitem__
方法
由于__iter__
方法需要返回迭代器, 先给出实现__getitem__
方法的可迭代对象示例
1 | class it1: |
迭代器
迭代器(iterator)就是实现了__next__
方法的对象, 该方法也是返回序列的当前元素, 它跟__getitem__
的区别就是, 当前元素的索引是保存在迭代器对象实例中, 而__getitem__
是
由python解释器自动创建的迭代器提供的索引
迭代器实例
1 | class it2: |
使用for迭代的过程
我们使用for
语句迭代一个对象(obj
)过程如下:
- 使用内置函数
iter
获取obj
对象的迭代器 (分两种情况, 第一种是通过__iter__
直接
获取对象的迭代器, 第二种是通过python解释器自动创建迭代器 - 获得迭代器后, 循环调用
next(iter)
获取元素,next
函数调用迭代器内部的__next__
方法以获得序列中的元素, 直到__next__
方法抛出StopIteration结束循环
生成器
生成器是迭代器的子集, 所以它也属于迭代器, 只是它的实现方式不一样, 生成器更简洁, 而且
它不需要像迭代器一样维护一个索引, 它是通过yield
语句来实现的
生成器函数实例
1 | def it3(text): |
代码在执行到yield
时, 将返回其后的值, 然后并不像return
语句一样退出, 而是挂起函数
的状态, 下次再从当前胃继续执行
生成器表达式
类似列表推导式, 只是方括号替换成大括号
1 | # 列表推导式 |
生成器除了实现简洁外, 它还有节省内存的优点, 它不是一次性构建整个结果列表, 它有延迟计
算的特点, 按需产生结果