在学习廖雪峰网站生成器时,看到练习题回答中的一个问题,感觉自己也很容易犯这样的错误。
# 生成器之杨辉三角
# 期待输出:
# [1]
# [1, 1]
# [1, 2, 1]
# [1, 3, 3, 1]
# [1, 4, 6, 4, 1]
# [1, 5, 10, 10, 5, 1]
# [1, 6, 15, 20, 15, 6, 1]
# [1, 7, 21, 35, 35, 21, 7, 1]
# [1, 8, 28, 56, 70, 56, 28, 8, 1]
# [1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
def triangles():
list1 = [1]
while True:
yield(list1)
list1.append(0)
list1 = [list1[i-1]+list1[i] for i in range(len(list1))]
n = 0
results = []
for t in triangles():
print(t)
results.append(t)
print(results)
n = n + 1
if n == 10:
break
if results == [
[1],
[1, 1],
[1, 2, 1],
[1, 3, 3, 1],
[1, 4, 6, 4, 1],
[1, 5, 10, 10, 5, 1],
[1, 6, 15, 20, 15, 6, 1],
[1, 7, 21, 35, 35, 21, 7, 1],
[1, 8, 28, 56, 70, 56, 28, 8, 1],
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
]:
print('测试通过!')
else:
print('测试失败!')
这段代码会测试失败的原因:
因为每次测试代码中for循环执行之初,会执行yield之后的append代码,对上个生成器末尾加0
故最后的results是:
[[1, 0], [1, 1, 0], [1, 2, 1, 0], [1, 3, 3, 1, 0], [1, 4, 6, 4, 1, 0], [1, 5, 10, 10,5, 1, 0], [1, 6, 15, 20, 15, 6, 1, 0], [1,7, 21, 35, 35, 21, 7, 1, 0], [1, 8, 28, 56, 70, 56, 28, 8, 1, 0], [1, 9, 36, 84, 126,126, 84, 36, 9, 1]]
根源在于没有清醒认识列表是可变类型
例子:
a = [1, 1]
p = []
p.append(a)
print(p)
a.append(0)
print(p)
输出结果:
[[1, 1]]
[[1, 1, 0]]
triangle()函数中的正确代码可以为:
def triangle():
yield(list1)
list1 = [list1[x] + list1[x + 1] for x in range(len(list1) - 1)]
list1.append(1)
list1.insert(0, 1)