[python] generator生成器(斐波那契数列、杨辉三角)理解,log分析

[python] generator生成器(斐波那契数列、杨辉三角)理解,log分析

认识generator

这里就不讲generator的定义了,各种教程都有写,这里只记录一下我自己对于generator的初学理解:

  • generator函数的基本应用方向,当一组数据有一定的关联规则,就可以使用generator来定义它的规则,以便根据规则和需求不断的生成数据
  • generator可以理解为是个对算法的包装,调用方式一般(简单的应用)是迭代,每次返回一个值,下次返回基于上次的值而计算出的值,直到迭代结束
  • generator的关键字是yield,一个方法包含yield,这个函数即为generator对象。generator方法中一般需要一个while语句,用于不断产生满足条件的值、且当条件不满足时结束generator的执行。在while中,当执行到yield,即会返回本次生成的值,本次执行到此为止;下次执行从yield行之后开始执行,到while中代码结束时并不会停止执行,将继续跳到while内部开头位置,并执行到yield,返回新生成的值才结束(下面有示例和log)

示例

1. 斐波那契数列

斐波拉契数列(Fibonacci),除第1个和第2个数外,任意一个数都是它前两个数相加的值:
1, 1, 2, 3, 5, 8, 13, 21, 34, …

代码

(注:为便于理解generator的执行流程,以下代码实现并不是最优化的实现)

def fibonacci(maxTimes):
    n = 1
    a = 0
    b = 1
    temp = 0
    print(f'(step 0) before while n = {n}; a = {a}; b = {b}; temp = {temp};')
    while n <= maxTimes:
        print(f'(step 1) in while before yield n = {n}; a = {a}; b = {b}; temp = {temp};')
        yield b
        print(f'(step 2) in while after yield n = {n}; a = {a}; b = {b}; temp = {temp};')
        temp = b
        b = a + b
        a = temp
        n += 1
        print(f'(step 3) in while end n = {n}; a = {a}; b = {b}; temp = {temp};')

# Test
for s in fibonacci(9):
    print(f'----- fibonacci-value = {s} -----')
    print()
Log
(step 0) before while n = 1; a = 0; b = 1; temp = 0;

(step 1) in while before yield n = 1; a = 0; b = 1; temp = 0;
----- fibonacci-value = 1 -----

(step 2) in while after yield n = 1; a = 0; b = 1; temp = 0;
(step 3) in while end n = 2; a = 1; b = 1; temp = 1;
(step 1) in while before yield n = 2; a = 1; b = 1; temp = 1;
----- fibonacci-value = 1 -----

(step 2) in while after yield n = 2; a = 1; b = 1; temp = 1;
(step 3) in while end n = 3; a = 1; b = 2; temp = 1;
(step 1) in while before yield n = 3; a = 1; b = 2; temp = 1;
----- fibonacci-value = 2 -----

(step 2) in while after yield n = 3; a = 1; b = 2; temp = 1;
(step 3) in while end n = 4; a = 2; b = 3; temp = 2;
(step 1) in while before yield n = 4; a = 2; b = 3; temp = 2;
----- fibonacci-value = 3 -----

(step 2) in while after yield n = 4; a = 2; b = 3; temp = 2;
(step 3) in while end n = 5; a = 3; b = 5; temp = 3;
(step 1) in while before yield n = 5; a = 3; b = 5; temp = 3;
----- fibonacci-value = 5 -----

(step 2) in while after yield n = 5; a = 3; b = 5; temp = 3;
(step 3) in while end n = 6; a = 5; b = 8; temp = 5;
(step 1) in while before yield n = 6; a = 5; b = 8; temp = 5;
----- fibonacci-value = 8 -----

(step 2) in while after yield n = 6; a = 5; b = 8; temp = 5;
(step 3) in while end n = 7; a = 8; b = 13; temp = 8;
(step 1) in while before yield n = 7; a = 8; b = 13; temp = 8;
----- fibonacci-value = 13 -----

(step 2) in while after yield n = 7; a = 8; b = 13; temp = 8;
(step 3) in while end n = 8; a = 13; b = 21; temp = 13;
(step 1) in while before yield n = 8; a = 13; b = 21; temp = 13;
----- fibonacci-value = 21 -----

(step 2) in while after yield n = 8; a = 13; b = 21; temp = 13;
(step 3) in while end n = 9; a = 21; b = 34; temp = 21;
(step 1) in while before yield n = 9; a = 21; b = 34; temp = 21;
----- fibonacci-value = 34 -----

(step 2) in while after yield n = 9; a = 21; b = 34; temp = 21;
(step 3) in while end n = 10; a = 34; b = 55; temp = 34;

Process finished with exit code 0

观察log可以发现:

  • (step 0) 只执行了1次,它在generator函数之中,且在while语句之前
  • 第一次,进入while,执行到且直接在yield返回生成的第一个值,并在Test代码中打印结果
  • 之后每次(除了最后一次),执行顺序都是 (step 2) ---- (step 3) ---- (step 1),并输出结果
  • 最后一次,仅执行了**(step 2)** ---- (step 3),没有执行到**(step 1)**,也没有输出结果,因为n > maxTimes了,不再满足while条件

2. 杨辉三角

杨辉三角如下:

           1
          / \
         1   1
        / \ / \
       1   2   1
      / \ / \ / \
     1   3   3   1
    / \ / \ / \ / \
   1   4   6   4   1
  / \ / \ / \ / \ / \
 1   5   10  10  5   1
  • 每行开头、结尾数字都是1
  • 每行其它数字都是它上行对应前后两数字之和(基于上图示)
代码

(注:为便于理解generator的执行流程,以下代码实现并不是最优化的实现)

def triangles_yang(maxLines):
    n = 1
    list_line = [1]  # 用于第一次返回1
    while n <= maxLines:
        yield list_line
        # 以下为除第一次之外的每次的计算过程
        pre_list_line = [1]  # 开头1
        for i, v in enumerate(list_line):
            if 0 < i < len(list_line):
                # 中间每一个数字是它上行对应前后两数字之和
                pre_list_line.append(list_line[i - 1] + v)
        pre_list_line.append(1)  # 结尾1
        list_line = pre_list_line  # 赋值给list_line,用于下次计算
        n += 1


# Test
for t in triangles_yang(12):
    print(t)

Log
[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]
[1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1]
[1, 11, 55, 165, 330, 462, 462, 330, 165, 55, 11, 1]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值