Python generator 生成杨辉三角

一、题目描述

先看来自于 廖雪峰老师的一道 Python 练习题

杨辉三角定义如下:

          1
         / \
        1   1
       / \ / \
      1   2   1
     / \ / \ / \
    1   3   3   1
   / \ / \ / \ / \
  1   4   6   4   1
 / \ / \ / \ / \ / \
1   5   10  10  5   1

把每一行看做一个list,试写一个generator,不断输出下一行的 list:

def triangles():
    pass

# 期待输出:
# [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]
n = 0
results = []
for t in triangles():
    results.append(t)
    n = n + 1
    if n == 10:
        break

for t in results:
    print(t)

 二、思路分析

我们先从第二行开始,看一下更通用的序列生成过程:

1、首尾两个元素固定是1

2、下一行的序列生成依赖于上一行

3、下一行实际需要生成的元素个数,是上一行序列长度-1

就比如

[1,1] -> [1,2,1]   L = [1,1]    2 = L[0]+L[1]    result = [1]+[2]+[1]=[1,2,1] 需要生成 2 一个元素

L = [1,1]
result = [1]
# 只需要循环一次
for i in range(len(L)-1):
   result.append(L[i]+L[i+1])
result.append(1)
print(result)

[1,2,1] -> [1,3,3,1]   L = [1,2,1]    3 = L[0]+L[1]   3 = L[1]+L[2]  result = [1]+[3,3]+[1] 需要生成 3,3 两个元素

L = [1, 2, 1]
result = [1]
# 需要循环两次
for i in range(len(L)-1):
   result.append(L[i]+L[i+1])
result.append(1)
print(result)

 

仔细观察,这段代码,是不是可以简写成 列表生成式

L = [1,1]
print( [1] + [ L[i]+L[i+1] for i in range( len(L)-1 ) ] + [1] )
L = [1,2,1]
print( [1] + [ L[i]+L[i+1] for i in range( len(L)-1 ) ] + [1] )

由此,我们得到一个从上一行序列生成下一行序列的,通用的表达式:

L = 上一行列表
[1] + [ L[i]+L[i+1] for i in range( len(L)-1 ) ] + [1]

 从 [1] -> [1,1] 是否也符合这个表达式呢?

考虑到 for i in range(0) 循环是不执行的

for i in range(0):
    print(i)

所以,L = [1]  result = [1]+[]+[1]=[1,1] 也是符合我们表达式的。

L = [1]
print( [1] + [ L[i]+L[i+1] for i in range( len(L)-1 ) ] + [1] )
L = [1,1]
print( [1] + [ L[i]+L[i+1] for i in range( len(L)-1 ) ] + [1] )
L = [1,2,1]
print( [1] + [ L[i]+L[i+1] for i in range( len(L)-1 ) ] + [1] )

至此,除了杨辉三角的第一行序列 [1],我们得到了一个通用的表达式,第一行序列 [1],就让它直接返回就好。

L = [1] 返回
从第二行开始
L = 上一行序列
L (下一行序列) = [1] + [ L[i]+L[i+1] for i in range( len(L)-1 ) ] + [1]

 三、generator 写法

我们把上面的思路,用 generator 函数语法写出来:

def triangles():
    L = [1]
    while True:
        # 第一次调用 next,保留函数现场 L=[1] 返回 [1]
        yield L
        # 第二次调用 next,从这里开始,取出函数现场 L=[1] 执行,然后循环
        # 直到碰到 yield 关键字,继续保留函数现场,然后返回
        L = [1] + [ L[i]+L[i+1] for i in range( len(L)-1 ) ] + [1]

n = 0
results = []
for t in triangles():
    results.append(t)
    n = n + 1
    if n == 10:
        break

for t in results:
    print(t)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值