关于列表是可变类型的问题

在学习廖雪峰网站生成器时,看到练习题回答中的一个问题,感觉自己也很容易犯这样的错误。

# 生成器之杨辉三角
# 期待输出:
# [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)

你可能感兴趣的:(关于列表是可变类型的问题)