zoukankan      html  css  js  c++  java
  • 关于“可变对象和不可变对象”及“生成器函数”和“列表生成式”的实例说明

    杨辉三角定义如下:

              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():
    # 期待输出:
    # [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():
        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('测试失败!')



    下面进入实际代码编写及细节说明过程:
    生成器是为了解决因元素个数极多、又有迭代公式而产生的浪费存储空间的函数式表达方式:有两种方式,请参考廖雪峰官网教程“生成器”
    方法一:弱方法
    def triangles():
       yield [1]     
    # 当某程序P1调用本生成器函数时,每遇到yield标志,就将相应的结果传送回去,中断此函数下面的程序,当P1再次调用此程序时,继续从上次中断
    # 的地方往下执行,直到遇到下一个yield站点,如此反复运行
    yield [1, 1] s = (1, 1)
    # 为了让 s 和 g 能够平行运行,互不影响,必须将 s 和 g 定义成不同的类型,以免改变 g 从而改变了 s中的内容,当然这并不是唯一的方法;
    # 也可以通过 s.copy(g),从而使s和g指向不同的地址,进而互不影响。
    # 所以一定要注意,对于list的复制要想清楚用途,到底是共用地址还是简单复制→分道扬镳; g
    = [1, 1] while True: g[0] = 1 for i in range(len(s) - 1): g[i + 1] = (s[i] + s[i + 1]) g.append(1) s = tuple(g) yield list(s)

    # 以下是测试部分
    n = 0
    results = []
    for t in triangles():
        print(t)
        results.append(t)
        print(results)
        n = n + 1
        if n == 10:
            break
    print(results)
    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('测试失败!')
    
    

    方法二:神操作,可以借鉴其精妙之处

    def triangles():  
        s = [1]
        while True:
            yield s
            s = [1] + [s[x]+s[x+1] for x in range(len(s)-1)] +[1]    
    # 并没有着急给s赋值,而是遍历自身的元素产生一个完整新的序列,而后才把新序列赋值给s # [s[x]+s[x+1] for x in range(len(s)-1)]采用了“列表生成式”的方法 # 整个函数是结合生成器generator 和 “列表生成式”两个思想完成的 # 生成器generator也可以当做可迭代对象进行遍历

    # 下面附带range(0)的解释
    a = [1,2,3,4,5,6,]
    for i in range(0):     # 不会报错,这个循环也不会执行,因为根本没产生可迭代的序列
        print('__',i,'__')
    
    
    
     

    待完善!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

  • 相关阅读:
    html5画布
    html5标签及语义化
    MarkDown:基础知识
    20180624_Git分支管理之多人协作
    20180624_Git管理之Feature分支
    20180619_Git 分支管理之bug分支
    20180618_Git分支管理策略, 不使用Fast forward模式.
    20180618_Git分支管里之解决冲突
    20180618_Git的分支管理
    20180618_在githhub上创建远程仓库,再克隆远程仓库的代码
  • 原文地址:https://www.cnblogs.com/Jie-Bian/p/11041421.html
Copyright © 2011-2022 走看看