#廖雪峰老师的练习题
杨辉三角定义如下:
1
/ \
1 1
/ \ / \
1 2 1
/ \ / \ / \
1 3 3 1
/ \ / \ / \ / \
1 4 6 4 1
/ \ / \ / \ / \ / \
1 5 10 10 5 1
把每一行看做一个list,试写一个generator,不断输出下一行的list:
# -- coding: utf-8 --
def triangles():
pass
#输出
n = 0
results = []
for t in triangles():
print(t)
results.append(t)
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(‘测试失败!’)
———–以上为题目内容——–
我的第一次答案:
# -*- coding: utf-8 -*-
def triangles():
l1 = [1]
n = 0
while 1:
if n != 0:
m = 0
lt = l1
while m! = n:
if m!= 0:
l1[m] = lt[m-1] + lt[m]
m = m+1
l1.append(1)
yield l1
n = n+1
‘测试失败!’
问题在备份lt
“lt = l1”,这句话是将lt指向了l1指向的对象,即它们俩是不同的变量指向了同一个对象
然后下面“l1[m] = lt[m-1] + lt[m]”和“l1.append(1)”都是操作的对象,所以一旦l1变了,那么lt这个备份也会变,所以并没有起到备份的作用
然后我将备份的方法换成了
lt = [t for t in l1]
这样写,lt就指向了一个新的对象,不会再受l1的影响
运行之后,测试代码中print打印出的样子看起来是没有问题的,
但是还是’测试失败!’
看了评论猜测原因是在
定义一个list:results = []
=> 定义了为空的result变量,没有指向任意的对象
然后for循环从生成器拿值操作list:results.appen(t)
=>result[0]这个变量指向了l1指向的变量
再次从生成器出来后,l1指向的变量 值就变了(即result[0]指向的变量),也即result[0]变了,第二次results.appen(t)时,result[1]也是和result[0]、l1一样指向同一个变量,所以最后result实际的内容并不是我看到的print出来的那样
然后我将代码中的“yield l1”改成
yield [y for y in l1]
这样每次生成器生成的值会是指向的一个新变量
result[0]、result[1]…他们也都每次指向的变量不一样
最终代码就是
# -*- coding: utf-8 -*-
def triangles():
l1 = [1]
n = 0
while 1:
if n != 0:
m = 0
lt = [t for t in l1]
while m != n:
if m!= 0:
l1[m] = lt[m-1] + lt[m]
m = m+1
l1.append(1)
yield [y for y in l1]
n = n+1
WHATEVER
评论区大神的代码是。。。
# -*- coding: utf-8 -*-
def triangles():
L=[1]
while True:
yield L
L=[L[0]]+[L[n]+L[n+1] for n in range(len(L)-1)]+[L[-1]]