[py]函数中yield多次返回,延迟计算特性-杨辉三角

搞清什么是杨辉三角

每行是一个数组,

第一行: [1]
第二行: [1, 1]
第三行: [1, 2, 2, 1]
...

画的好看点就是,不过没啥卵用

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

打印杨辉三角

首先要解决一个函数,多次返回值, 我们知道py函数返回多个值,没啥问题. 但是要多次返回值呢?需要借助生成器来完成, 生成器的好处是可以保留现场,延迟操作

套路是 函数里使用yield关键字,相当于return, 不过可以有多个yield,但是不可以有多个return.

yield可以返回一个generator类型的值, 可以for in遍历

那么可不可以手动创建一个yield值呢? 可以

方法: 将列表推导式(一股脑生成所有值,为了简化for代码)的方括号改成圆括号即可.

x = [x * x for x in range(10)]
g = (x * x for x in range(10)) #2种遍历方法: 法1: next(g) 需处理StopIteration异常,  法2: for i in g

>>> next(g)
0
>>> next(g)
1
>>> next(g)
4
>>> next(g)
...

生成器小结:

小结

  • 凡是可作用于for循环的对象都是Iterable类型;
  • 凡是可作用于next()函数的对象都是Iterator类型,它们表示一个惰性计算的序列;
  • 集合数据类型如list、dict、str等是Iterable但不是Iterator,不过可以通过iter()函数获得一个Iterator对象。
  • Python的for循环本质上就是通过不断调用next()函数实现的,例如:
    for x in [1, 2, 3, 4, 5]:
    pass

    实际上完全等价于:

    # 首先获得Iterator对象:
    it = iter([1, 2, 3, 4, 5])
    # 循环:
    while True:
    try:
        # 获得下一个值:
        x = next(it)
    except StopIteration:
        # 遇到StopIteration就退出循环
        break

先搞清楚生成器-用在函数里,多次返回值,具有保留现场,延迟操作的功效

这个程序执行过程, for语句一股脑构造好arr数据后一次性返回

def sc(N):
    arr = []
    for i in range(N):
        arr.append(i**2)
    return arr

for i in sc(10):
    print(i)

改成yield(相当于return,所以一定写在函数里,但可以写多条.)
执行过程: 遇到yield即刻保留现场,yield的内容返回给调用者. 再次调用函数时,从上次yield下一条语句开始执行,遇到下一个yield直接返回内容.

def sc(N):
    for i in range(N):
        yield i ** 2

for i in sc(10):
    print(i)

如果还不太清楚,且看

yield返回的是generator

def odd():
    print('step 1')

g = odd()
print(type(odd)) #<class 'function'>
print(type(g))   #<class 'NoneType'>
def odd():
    print('step 1')
    yield (1)
    print('step 2')
    yield (2)
    print('step 3')
    yield (3)

g = odd()
print(type(odd))#<class 'function'>
print(type(g))  #<class 'generator'>

yield调用过程, 和调用的2种方法

def odd():
    print('step 1')
    yield (1)
    print('step 2')
    yield (2)
    print('step 3')
    yield (3)

g = odd()
print(type(g))
print(type(odd))

#遍历生成器,方法1: 最后没值了后异常(StopIteration)
next(g)
next(g)
next(g)

#遍历生成器,方法2: 不用关心StopIteration异常
for i in g:
    print(g)

---
step 1
1
step 2
2
step 3
3

打印杨辉三角

# 期待输出:

# [1]
# [1, 1]
# [1, 2, 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次返回[1]
#第2次返回[1, 1]
#第3次返回[1, 2, 1]
# 每行的模式
[1, 2, 2, 1] = [1,2]+[2,1]

for i in range(n):
    i=i+1
    arr = list(range(1, i))
    arr = arr + list(reversed(arr))

- 其次yield实现多次返回

def yanghui():
    yield [1]
    yield [1, 1]
    yield [1, 2, 2, 1]

for i in yanghui():
    print(i)

---
[1]
[1, 1]
[1, 2, 2, 1]

最终实现

def yanghui(n):
    for i in range(n):
        #
        i=i+1
        arr = list(range(1, i))
        arr = arr + list(reversed(arr))
        # list(range(1, 1)) ==> []
        if arr == []:
            arr = [1]
        yield arr

for i in yanghui(10):
    print(i)

原文地址:https://www.cnblogs.com/iiiiiher/p/8330183.html

时间: 2024-07-30 04:59:40

[py]函数中yield多次返回,延迟计算特性-杨辉三角的相关文章

理解 ES6 语法中 yield 关键字的返回值

在 ES6 中新增了生成器函数的语法,本文解释了生成器函数内 yield 关键字的返回值. 描述 根据语法规范,yield 关键字用来暂停和继续执行一个生成器函数.当外部调用生成器的 next() 方法时,yield 关键字右侧的表达式才会执行. 执行结果会转化为一个对象(包含两个属性, value 和 done),作为 next() 方法的返回值. 对于  var foo = yield expression 语句,yield 左侧变量 foo 的值将在下一次调用 next() 方法时获得,并

以杨辉三角为例,从内存角度简单分析C语言中的动态二维数组

学C语言,一定绕不过指针这一大难关,而指针最让人头疼的就是各种指向关系,一阶的指针还比较容易掌握,但一旦阶数一高,就很容易理不清楚其中的指向关系,现在我将通过杨辉三角为例,我会用四种方法从内存的角度简单分析动态二维数组,若有不足或错误之处,还请指出! 在讲这之前,以一维数组为例,先重新认识一下数组: int array[5] = {1, 2, 3, 4, 5}; 首先数组名称是该数组的首地址常量,即数组名称就是指针,就有&array[0] == array! 那么我们可以推出*array ==

ACM中杨辉三角的多种解法

杨辉三角的多种解法 杨辉三角的相信大家很熟悉吧,但是大家能用多少中方法写出来呀,一般人都只会想到两种,递归和二项式.当用递推时,有时在解题是根本没必要需要那么多呀,而只要杨辉三角的某一行,数据小时,我们可以用二项式来计算,但是数据比较大时,二项式算也是很麻烦的,那么还有其它的方法吗?所以下面我就介绍几种计算杨辉三角的方法吧. 主要要记住第四种.... 完整版下载:http://download.csdn.net/detail/u010304217/7750997 博客版下载:http://dow

利用yield关键字输出杨辉三角

最近学习了下python,发现里面也有yield的用法,本来对C#里的yield不甚了解,但是通过学习python,对于C#的yield理解更深了!! 不多说了,小学生水平的表达能力伤不起.... 直接上代码: using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; namespace ConsoleApplication2 {

Python 中使用 for、while 循环打印杨辉三角练习(列表索引练习)。

Python中使用for while循环打印杨辉三角练习(列表索引练习). 杨辉三角是一个由数字排列成的三角形数表,一般形式如下: 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组成的,而其余的数则是等于它肩上的两个数之和. 方法一: __author__ = 'Brad' n = int(input('请输入你想打印杨辉三角

写4个同名方法,实现两个整数、两个实数,一个实数一个整数,一个整数一个实数之间的求和。在主调函数中调用这4个方法计算相关的值。(方法的重载)

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace ConsoleApplication7 8 { 9 class Program 10 { 11 static void Main(string[] args) 12 { 13 //整数相加 14 int a = 1; 1

Js中,刚学完二维数组和函数,输出杨辉三角

var a= Array(5);for ( var i= 0;i<a.length;i++){ a[i]=Array(i+1); a[i][0]=1; for(var j=0;j<a[i].length;j++) { if(i==j) { a[i][j]=1 } else{ if((i-1)>=0&&(j-1)>=0) { a[i][j]=a[i-1][j-1]+a[i-1][j];} } } }; for(var i in a){ for(var j in a[i

给定一个非负索引 k,其中 k ≤ 33,返回杨辉三角的第 k 行。

从第0行开始,输出第k行,传的参数为第几行,所以在方法中先将所传参数加1,然后将最后一行加入集合中返回. 代码如下: public static List<Integer> generateII(int row){ ++row; List<Integer> list = new ArrayList<Integer>(); int[][] arr = new int[row][row]; for(int j = 0;j<row;j++) { for(int k =

返回杨辉三角前 n 层的数字

我的思路后来被证实是比较慢哈,思路很简单,递归地一行一行地往里插.是这样的: vector<vector<int>> generate(int numRows) { if (numRows < 1){ return vector<vector<int>>(); } if (numRows == 1){ return vector<vector<int>>{vector<int>{1}}; } auto&&am