最近学习了 python 的迭代器和生成器, 生成器的是有一个特点的, 就是用到数据时才会去取来用! 请观察下面代码思考问题, 想明白了, 你就会明白什么是惰性计算了!
- def add(s, x):
- return s + x
- def gen():
- for i in range(4):
- yield i
- base = gen()
- for n in [1, 10]:
- base = (add(i, n) for i in base)
- print(list(base))
输出:[20, 21, 22, 23] 很不解吧, 请往下看
这个题的关键点在于下面几点:
1. 因为循环在做的事是用生成器表达式生成数据, 而生成器有个惰性计算特点, 导致把我们引上一条不归路, 我们被假象迷惑, 其实它并没做任何事, 而是单纯的走了两边过程
2. 生成器就是等到用的 (比如: 打印或者 next 函数取值等) 得时候才会进行计算生产, 所以等到最后打印的时候才开始计算
3. 当开始生产数据的时候, 循环已经进行的两次 n 的值也因此变成了 10
4. 第一次循环生成器生产数用到的 base 还是绑定的 gen 取 0,1,2,3 经过加工(add 函数加操作), 生成器生产出 10,11,12,13, 然后 base 顺利占据了生成器
5. 第二次循环在进行向 base 取值时, base 已经不再是 gen 而是上次循环重新绑定的 base, 所以取到的值是 10,11,12,13 然后经过自己的加工生产出 20,21,22,23, 到这时大功告成.
6. 千万别把 for n in [1,10] 想成了 for n in range (1,10)
7. 可能 n 变成了 10 很意外, 但是理解了惰性之后也就明白了为神魔 n 在为 1 时没进行运算
8. 一定要理清 base 在某时某刻的绑定关系, 尤为重要
希望这篇博客能帮助你们! 谢谢! 轻点问候!
来源: http://www.bubuko.com/infodetail-2693584.html