Python的Generator
教程及题目链接
关于yield的博客
目前遇到的一个问题是关于生成器yield的一些疑惑,即教程里那一道杨辉三角
一开始的理解
一开始我认为python的yield是类似压栈存储数据的作用(运行流程类似断点),具体原理可以参考上面的博客,即yield相当于一次调用的终点,然后下一次是从上面yield的地方继续下去的。
但是数据上的存储不是简单的数据压栈,因为yield存进去的不是数据而是地址,可以看一下下面这个代码的运行结果。
1 | def triangles(): |
2 | L = [1] |
3 | while True: |
4 | yield L |
5 | L += [0] |
6 | |
7 | |
8 | n = 0 |
9 | results = [] |
10 | for t in triangles(): |
11 | results.append(t) |
12 | n = n + 1 |
13 | if n == 5: |
14 | break |
15 | print(results) |
运行结果:
[[1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0]]
可以看出results里的所有数据都是同一个元素
另外一个修改后的代码
1 | def triangles(): |
2 | L = [1] |
3 | while True: |
4 | yield L |
5 | L = L + [0] #改动的地方 |
6 | |
7 | |
8 | n = 0 |
9 | results = [] |
10 | for t in triangles(): |
11 | results.append(t) |
12 | n = n + 1 |
13 | if n == 5: |
14 | break |
15 | print(results) |
运行结果:
[[1], [1, 0], [1, 0, 0], [1, 0, 0, 0], [1, 0, 0, 0, 0]]
个人理解
python里面的数据都是动态的,L += [0]只是基于同一个地址进行修改,所以在results里面的元素其实都是指向同一个list,而L = L + [0]是形成了一个新的数据,所以在yield的时候导入了“新地址”(至于是否是用一个地址,还是新的地址但是是同一个值,原因无法确定)
但是这一个结果告诉我们,python里面L = L + [0] 和 L += [0]两个式子并不是完全等价的,这是一个和C语言不同的地方