背景介绍
- 整理面试题,开始刷题【python】【测试】【测开】相关。
解决方案
- 人无我有,人有我精
面试题03:说一下你对Python中迭代器和生成器的理解。
点评:很多人面试者都会写迭代器和生成器,但是却无法准确的解释什么是迭代器和生成器。如果你也有同样的困惑,可以参考下面的回答。
- 迭代器是实现了迭代器协议的对象。
跟其他编程语言不同,Python中没有用于定义协议或表示约定的关键字,像interface、protocol这些单词并不在Python语言的关键字列表中。
Python语言通过魔法方法来表示约定,也就是我们所说的协议,而__next__和__iter__这两个魔法方法就代表了迭代器协议。
可以通过for-in循环从迭代器对象中取出值,也可以使用next函数取出迭代器对象中的下一个值。
- 生成器是迭代器的语法升级版本,可以用更为简单的代码来实现一个迭代器。
什么是迭代器
顾名思义,迭代器就是用于迭代操作(for 循环)的对象,它像列表一样可以迭代获取其中的每一个元素,任何实现了 「next」 方法 (python2 是 next)的对象都可以称为迭代器。
它与列表的区别在于,构建迭代器的时候,不像列表把所有元素一次性加载到内存,而是以一种延迟计算(lazy evaluation)方式返回元素,这正是它的优点。比如列表含有中一千万个整数,需要占超过400M的内存,而迭代器只需要几十个字节的空间。因为它并没有把所有元素装载到内存中,而是等到调用 next 方法时候才返回该元素(按需调用 call by need 的方式,本质上 for 循环就是不断地调用迭代器的next方法)。
迭代器实操【可能会让你手写的】
写生成斐波那契数列的迭代器
- 迭代器
class Fib(object): def __init__(self, num): self.num = num self.a, self.b = 0, 1 self.idx = 0 def __iter__(self): return self def __next__(self): if self.idx < self.num: self.a, self.b = self.b, self.a + self.b self.idx += 1 return self.a raise StopIteration()
什么是生成器
生成器本质上还是一个迭代器
知道迭代器之后,就可以正式进入生成器的话题了。普通函数用 return 返回一个值,和 Java 等其他语言是一样的,然而在 Python 中还有一种函数,用关键字 yield 来返回值,这种函数叫生成器函数,函数被调用时会返回一个生成器对象,「生成器本质上还是一个迭代器」,也是用在迭代操作中,因此它有和迭代器一样的特性,唯一的区别在于实现方式上不一样,后者更加简洁。
生成器实操【可能会让你手写的】
用生成器的语法来改写上面的代码,代码会简单优雅很多。
def fib(num): a, b = 0, 1 for _ in range(num): a, b = b, a + b yield a
结尾
- 好好复习,明天见!
关注「测试开发囤货」公众号回复「编程」,送你一本全彩 Python 编程电子书。