Python生成器

来源:互联网 发布:北京seo网站排名优化 编辑:程序博客网 时间:2024/05/18 12:37

Python生成器

1 Python式生成器

从语法上讲,生成器是一个带yield语句的函数。一个函数或者子程序只返回这一次,但是一个生成器能暂时停止并返回一个中间的结果--那就是yield语句功能,返回一个值给调用者并暂停执行。当生成器的next()方法被调用的时候,它会准确的从离开的地方继续向下(当它返回[一个值以及]控制给调用者时)。

2 协同程序

生成器的另外一个方面更加强力--协同程序的概念。协同程序是可以运行的独立程序调用。可以暂停或者挂起,并从程序离开的地方继续或者重新开始。在调用者和(被调用的)协同程序也有通信。举例来说,当协同程序暂停的时候,我们能从其中获得一个中间的返回值,当调用回到程序中时,能够传入额外或者改变了的参数,但仍能从我们上次离开的地方继续,并且所有状态完整。挂起返回出中间值并多次继续的协同程序被称为生成器。

当等待一个生成器的时候,生成器现在能返回控制。在调用的生成器能挂起(返回一个结果)之前,调用生成器返回一个结果而不是阻塞等待那个结果返回。

3 举例

#/usr/bin/env python
#-*- coding: utf-8 -*-
def triangles():
    L = [1]
    while True:
        yield L
        L.append(0)     #补充0后的状态[1,0]
        L = [L[i-1] + L[i] for i in range(len(L))]  #生成第1

n = 0
for t in triangles():
    print(t)
    n = n + 1
    if n == 10:
        break

输出



'''
解析:
已知 L:[1,0] ,len(L):2 ,range(0,2)不包含2
列表生成式[L[i - 1] + L[i] for i in range(len(L))]会生成什么鬼?
i=0 L[i-1]+L[i] == 0+1 == 1
i=1 L[i-1]+L[i] == 1+0 == 1
所以这个列表生成式最终生成了 [1,1],然后将它赋给L。然后yield L.

然后生成第2行:

def triangles():
    L = [1]
    while True:
        yield L #生成第2行时的开局状态,L:[1,1]
        L.append(0) #0[1,1,0]
        L = [L[i - 1] + L[i] for i in range(len(L))] #生成第2

算法:
row
0    1
1    1 1
2    1 2 1
3    1 3 3 1
4    1 4 6 4 1
------------------
col  0 1 2 3 4

然后大家可以发现如下几个事实:
1.col==0 的这一列上的元素总是 1 例如T(0,0),T(1,0),T(4,0)
2.col==row 的这一列上的元素总是 1, 例如 T(0,0),T(1,1),T(4,4)
3.(敲黑板,重点)  T(row,col)上的元素等于 T(row-1,col-1)+T(row-1,col)
例如 T(4,3) == T(3,2)+T(3,3)  4 == 3 + 1
例如 T(4,2) == T(3,1)+T(3,2)  6 == 3 + 3
虽然讲得很有道理的样子,然而机智的小伙伴们还是一眼就看出了破绽。
介绍事实3时候,为什么不拿T(0,0),T(1,0)T(1,1)这样的元素举例?
按我的分析 T(0,0) == T(-1,-1)+T(-1,0) ,这不翻车了么。妈蛋的,确实翻车了!

def triangles():
    L = [1] #所以在这个解法里,作者很机智,直接给第0行初始化一个[1]
    while True:
        yield L  # 生成第0行,问题解决。

我们再来看看第1行的情况,
T(1,0) == T(0,-1)+T(0,0) ,T(0,0)1T(0,-1)不存在。
T(1,1) == T(0,0)+T(0,1)  ,T(0,0)1T(0,1)不存在
根据事实1,事实2我们知道T(1,0)T(1,1)都是1,将已知量带入我们的式子.
1 = x+1 x=0
1 = 1+x x=0
发现了没有,要想让这个算法进行下去,第0行元素命格不行【八字欠零,五行(xing2)缺零】,一共缺了前后两个零。

#在假想的情况下,第0行如果能像图中这样补上两个0,那么生成第1行的时候就轻松愉快了。
#上边我们分析过了生成第1行需要的T(0,-1)T(0,1),现在已经到货.
r
0 [0 1 0]
1    1 1
2    1 2 1
3    1 3 3 1
4    1 4 6 4 1
------------------
c -1 0 1 2 3 4

那就这样定了,给第0行补0.

def triangles():
    L = [1]
    while True:
        yield L
        L.append(0) #作者真的给上一行补了0,可是为什么只补了一个0
        L = [L[i - 1] + L[i] for i in range(len(L))] #生成第1

学习切片的时候,廖大说过列表倒数第一个元素的索引是-1
所以,我们在上图里看到的T(0,-1),python列表里是绕到后边去了。
自然界里的列表[0,1,0],各元素索引依次为 -1,0,1 python里的列表[1,0],各元素索引依次为0,1/-1,就像一个环,两端粘在了一起。

'''
 

0 0
原创粉丝点击