【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。

杨辉三角定义如下:

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

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

该题目考查生成器的应用。一般的思路是,首先在每一行输出一个1,随后通过循环,位置i(从2开始)的数是上一行i与i-1位置的数之和,当i与上一行数字个数相同时,循环终止,最后再添加进一个1,形成新的一行。

基于这个基本思路,将python的生成器运用到里面,有两种常见的写法:

一种写法如下:

1 def triangles():#杨辉三角的一种生成方法
2     l = [1]
3     while True : 
4          yield l
5          for i in range ( 1,len (l) ) :
6              l [i] =  h [i] + h [i-1] 
7          l.append (1)
8          h = l[:]

另外一种写法如下,运用了list的生成式:

1 def triangles():
2     l = [1]    
3     while True :
4        yield l
5        l = [1] + [ l[i] + l[i+1] for i in range ( len (l) - 1)] + [1]

可以看到,以上两种写法都是相当简洁的。一开始这两个代码看不太懂,比如说为啥第一种写法里一开始h里面没有数,却也能够正常执行?主要是对于生成器的yield机制不明白,以及对于range的用法不是特别清楚。以下就这两点分别解释。

首先,当函数中出现了yield之后,该函数就不再被视为函数,而视为一个生成器。此时,整个函数被使用的语句流程会发生改变,一般的函数都是调用的时候从函数入口进,发现return或函数执行完毕后返回,而生成器函数则是每次调用函数执行,执行到yield返回,下次再调用函数的时候从上次yield返回处继续执行。

其次,range的用法中是,如果是【range(x,x) 其中x是常量】的形式,range依然返回空。故在上述代码的for循环中,由于在第一次试图循环的时候,后面的range要么是range(1,1)要么是range(0),故都会成功避开i或者h没有实际值的循环,执行接下来的部分。当第二次试图循环开始时,i和h内的内容都已经满足条件了,所以就能正常运行了。

还有一种我看到的最简单的写法:

1 def triangles():
2     L = [1]
3     while True:
4         yield L
5         L= [(L + [0])[i] + ([0] + L)[i] for i in range(len(L)+1)]

这一种写法直接去掉了第二种写法里每次L两边额外插入的[1],使其变为了一个完整的一个list生成式,可以说是相当精妙。

那么,这种写法为什么也可以呢?我们再来分析一下杨辉三角的性质,这样,为了直观理解,我们先利用上面的代码,举一个运行中的过程例子。

比如,L此时为[1,1](杨辉三角第二行),现在需要求第三行。根据第五行的生成式,将按照以下步骤进行计算:

1.L尾部加0,得到[1,1,0],我们称之为tempL1

2.L首部加0,得到[0,1,1],我们称之为tempL2

3.现在,根据之后的for循环,L最终要被赋值成由tempL1与tempL2对应的每个相同位置数字之和所组成的列表,经过计算,这个新的L应该为[1,2,1]。居然确实是杨辉三角的第三行!

相信聪明的观众已经明白了,这个最简单的写法是利用了杨辉三角本身的对称性质,让同一行错开一位竖式相加,得到的就是下一行的结果。同时,利用python里面本身就极为方便的列表扩展写法和列表生成式,才有了第三种如此简洁的写法~

 

目录
相关文章
|
1月前
|
存储 算法 调度
【复现】【遗传算法】考虑储能和可再生能源消纳责任制的售电公司购售电策略(Python代码实现)
【复现】【遗传算法】考虑储能和可再生能源消纳责任制的售电公司购售电策略(Python代码实现)
144 26
|
1月前
|
测试技术 开发者 Python
Python单元测试入门:3个核心断言方法,帮你快速定位代码bug
本文介绍Python单元测试基础,详解`unittest`框架中的三大核心断言方法:`assertEqual`验证值相等,`assertTrue`和`assertFalse`判断条件真假。通过实例演示其用法,帮助开发者自动化检测代码逻辑,提升测试效率与可靠性。
202 1
|
1月前
|
机器学习/深度学习 算法 调度
基于多动作深度强化学习的柔性车间调度研究(Python代码实现)
基于多动作深度强化学习的柔性车间调度研究(Python代码实现)
129 1
|
23天前
|
测试技术 Python
Python装饰器:为你的代码施展“魔法”
Python装饰器:为你的代码施展“魔法”
200 100
|
23天前
|
开发者 Python
Python列表推导式:一行代码的艺术与力量
Python列表推导式:一行代码的艺术与力量
233 95
|
1月前
|
Python
Python的简洁之道:5个让代码更优雅的技巧
Python的简洁之道:5个让代码更优雅的技巧
189 104
|
1月前
|
开发者 Python
Python神技:用列表推导式让你的代码更优雅
Python神技:用列表推导式让你的代码更优雅
340 99
|
23天前
|
缓存 Python
Python装饰器:为你的代码施展“魔法
Python装饰器:为你的代码施展“魔法
133 88
|
1月前
|
IDE 开发工具 开发者
Python类型注解:提升代码可读性与健壮性
Python类型注解:提升代码可读性与健壮性
204 102
|
28天前
|
监控 机器人 编译器
如何将python代码打包成exe文件---PyInstaller打包之神
PyInstaller可将Python程序打包为独立可执行文件,无需用户安装Python环境。它自动分析代码依赖,整合解释器、库及资源,支持一键生成exe,方便分发。使用pip安装后,通过简单命令即可完成打包,适合各类项目部署。

推荐镜像

更多