33-高级特性之generator(1)

摘要:
例如,count=yield,当代码到达这一行时,生成器函数将在遇到yield后立即暂停,并保存当前状态以进行恢复。暂停yield时,将yyy返回给调用函数{对于此函数,yield相当于returnyyy}如上所述,yield首先挂起当前生成器函数,然后将数据返回给调用功能。

1. 列表生成式

################列表生成式
#method_1 {太原始,不推荐}
L = []
for i in range(1,11): #[1,11)
    L.append(i*i)
print(L)


#method_2
#######最佳的办法
L1 = [x*x for x in range(1,11)]
print(L1)

L2 = [x*x for x in range(1,11) if (x%2 == 0)]
print(L2)

L3 = [m+n for m in "ABC" for n in "XYZ"]
print(L3)

import os
dir = [d for d in os.listdir('.')] #.表示当前目录下
print(dir)

#考虑到for 可以同时迭代两个甚至更多变量,把他应用到 列表生成式
dict = {'name':'haozhang', 'gender':'male', 'city':'HG'}
for k,v in dict.items():
    print(k,':',v)
print("
")

L4 = [k+':'+v for k,v in dict.items()]
print(L4)

#
L = ['ABC', 'Hong', 'KONG']
print(L)
L5 = [s.lower() for s in L]
print(L5)

L6 = ['ABC', 'HongKong', 123, '456']
print(L6)
L7 = [s.lower() for s in L6 if isinstance(s, str)]
print(L7)
L8 = [s.lower() for s in L6] #没有过滤整数,会报错

2. generator初步:

  • 理解yield关键字的作用:

  • 首先yield就像一个中断源,代码执行到yield处就中断,cpu执行其他函数去了。例如,count = yield yyy,代码到这一行,刚刚碰到yield就暂停本generator函数,并保存当前状态等待恢复。
  • 直到next(对象名),或者send(实参),来激活这一行语句。
  • 暂停yield的同时,向主调函数返回yyy {就这个功能而言,yield yyy等价于return yyy}
  • 终上所述,yield首先是挂起当前的generator函数,然后可以返回一个数据给主调函数(即使用了next(),send(),或者用for迭代这个generator函数的语句)。
  • 用for迭代这个generator函数 本质还是利用了next(对象名)
  • 代码测试:

    测试generator 以创建list作为对比

    L = [x*x for x in range(1,11)]
    print(L)

    G = (x*x for x in range(1,11)) #Generator表达式
    print(G)
    print(next(G))
    print(next(G))
    print(" ")

    g = (xx for x in range(1,11)) #构造了一个generator类并返回了一个它的对象
    for y in g: #迭代g的每一项x
    x
    print(y)
    print(" ")

    测试第二种generator :Generator函数 采用函数方式

    def fib(n):
    i,a,b = 0,0,1 #fib(0) = 0, fib(1) = 1, fib(2) = 1
    while i < n: #执行n-1次,i的范围是[0,n-1],因为默认是fib(1),所以后面都是返回fib(n)
    print(b)
    a,b = b,a+b
    i = i + 1
    return 'done'
    fib(6)
    print(" ")

    采用yield关键字,用generator实现

    def G_fib(n): #实际上等价于创建了一个generator类,虽然表面上是一个函数
    i,a,b = 0,0,1
    while i < n: #[0,n-1]
    yield b #此次返回并暂时挂起
    a,b = b,a+b
    i = i + 1
    g2 = G_fib(6) #返回一个generator类创建的对象g2
    print(g2)
    for x in g2: #迭代g2中的每一项即:fib(i)
    print(x)
    print(" ")

    创建一个产生所有奇数的generator

    def odd():
    i = 1
    while True:
    yield i
    i = i + 2
    g3 = odd()
    print(next(g3))
    print(next(g3))
    print(next(g3))
    print(" ")

    理论上可以通过for x in g3 遍历足够多的,或者说是所有的奇数,但这里没有必要

    {即节省内存,因为每次只会创建一个item;另外,非常的简洁地可以代表一个无穷的stream} 实现一个2^n{乘方}

    def powtwo(n):
    i = 1
    while i <= n: #[1,n],操作了n次
    yield 2 ** i
    i += 1

    for x in powtwo(5): #计算2^5
    print("中间过程依次是:",x)
    print("the result is = ",x)
    print(" ")

    '''
    实现一个假设我们有一个快餐连锁店的日志。

    日志的第四列是每小时售出的披萨数量,我们想对近5年的这一数据进行求和。 假设所有数据都是字符,不可用的数据都以"N/A"表示

    with open('sells.log') as file:
    pizza_col = (line[3] for line in file) #取第4列,构建一个tuple
    per_hour = (int(x) for x in pizza_col if x != 'N/A') #依据上面的tuple构建generator表达式
    print("Total pizzas sold = ",sum(per_hour))
    '''

    #########################################################################################

    '''
    最后一个主题:获取generator中,用return关键字返回的值
    {因为现在只会返回yield关键字所带的值}

    通过解析StopIteration的内容获取return关键字后的值 以获取杨辉三角的最后return的'haozhang'为例

    '''

    做法1

    def triangles():
    N = [1] #要求返回N为list
    while True:
    yield N
    N.append(0) #辅助元:处理每一行两边{左边一个1,右边一个1},保证它们在下一行依旧为1:0+1还是1
    #append完之后,本行{假设为k-1} 新增N[k] = 0,同时在python中N[k]作为倒数第一个元素,也为N[-1]
    #具体实现方法:对于下一行{假设是k}的N, N[0] = N[-1]+N[0],N[k] = N[k-1]+N[k]
    N = [N[i-1]+N[i] for i in range(len(N))]

    i = 0
    for L in triangles(): #匿名创建了triangles的generator对象,并迭代
    print(L)
    i += 1
    if (i == 10): #打印10行
    break
    print(" ")

    做法2:错位相加{L1左边和L2右边各自添加一个[0],即长度加1} [0]+N等价于在N左边加了一个元素0,N+[0]等价于在N右边加了一个元素0{可在控制台测试} zip(x, y)等价于:若x=[x1,x2], y=[y1,y2], 则zip(x,y) = [(x1,y1), (x2,y2)]

    def triangles_2():
    N = [1]
    while True:
    yield N
    N = [sum(i) for i in zip([0]+N, N+[0])]
    j = 0
    for L2 in triangles_2():
    print(L2)
    j += 1
    if (j == 10): #输出10行即停止
    break
    print(" ")

    加入try-catch实现把return关键字返回的值打印出来

    def My_Triangle(n):
    N = [1]
    i = 0
    while (i < n): #[0,n-1]次
    yield N
    N = [sum(i) for i in zip([0]+N, N+[0])]
    i += 1
    return "haozhang is ok" #我想把这个也拿出来!

    GT = My_Triangle(10)
    while True:
    try:
    x = next(GT)
    print(x)
    except StopIteration as e:
    print("Generation return value is: ", e.value)
    break

  • 理解send()的作用:

  • next()等价于send(None),系统向generator发信号“在中断处重新启动”就是send(实参)的功劳,send()才是核心。
  • send(数据值)等价于 给yield左边的变量赋值,例如:count = yield x,当使用 send(555)激活上述的yield时,等价于执行 count = 555,然后再执行count=yield的下一句代码
  • 终上所述,send(实参)可以给generator函数传入数据,并同时激活这个generator函数
  • 代码测试:

    def stupid_fib(n):
    index = 0
    a = 0
    b = 1
    while index < n:
    sleep_cnt = yield b
    print('let me think {0} secs'.format(sleep_cnt))
    time.sleep(sleep_cnt)
    a, b = b, a + b
    index += 1

    print('-'10 + 'test yield send' + '-'10)
    N = 20
    sfib = stupid_fib(N) #得到一个generator对象
    fib_res = next(sfib) #启动generator
    while True:
    print(fib_res)
    try:
    fib_res = sfib.send(random.uniform(0, 0.5)) #给函数传入暂停时长sleep_cnt,并重新激活generator
    except StopIteration:
    break

参考文献:

  1. http://python.jobbole.com/86069/
  2. 尚学堂python视频
  3. 廖雪峰python3

免责声明:文章转载自《33-高级特性之generator(1)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇js设置自动刷新vue项目中,不需前端编译打包,随时修改维护数据下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

pta作业·博客第一篇

今年是大二下学期,也是专业课集中学习的开始,这是本学期的第一篇博客。由于是新手上路,写的不好的地方还请各位大神指点一下。这篇博客围绕这一个月来学习java的心得体会,当然,代码是少不了的,主要是以pta上的三次作业为参考。写这篇博客目的在于自我反思,为以后的学习提供一个对比物。接下来,我将尝试用这篇博客来解释其中的种种困难,看不下去的朋友可以到此止住了。...

Hexo+Github--搭建个人博客(二)主题配置

安装完hexo后,我们便可以开始使用hexo,如果我们想更换主题使得网站更加简洁或者酷炫,那么我们可以进行主题更换。主题有很多,下面以NexT主题为例, 讲下如何更换主题: 一、NexT主题安装 Hexo提供了更换主题模块,进入你的博客部署文件夹,可以看到有个themes文件夹,这个文件夹就是用来存放主题的 首先我们使用git clone NexT主题到主...

windows 系统 MySQL_5.6.21安装教程

  1、双击安装文件 mysql_installer_community_V5.6.21.1_setup.1418020972.msi,等待安装界面出现,见下图:   2、勾选:I accept thelicense terms,点击Next,见下图:   3、选择Custom,点击Next,见下图   4、 4.1打开支线,根据服务器操作系统类型(32位...

mis系统的技术需求

  所谓MIS(管理信息系统--Management Information System)系统,主要指的是进行日常事务操作的系统。这种系统主要用于管理需要的记录,并对记录数据进行相关处理,将处理的信息及时反映给管理者的一套网络管理系统。   开发一个mis系统需要用到eclipse,还需要tomcat和mySQL。   tomcat安装、配置过程:首先下...

js中 转义字符

(1)针对双引号“”的使用: html= "<a href="javascript:void(0)" onclick="getSubContent('" +(choices[next])[0]+ "','" +(choices[next])[1]+ "','" +(choices[next])[2]+ "','" +((choices[next])...

最好的Maya 2008 安装详解 教程(转载)

最好的Maya 2008 安装详解 教程(转载) 这篇教程是我见过的最好的Maya 2008的安装教程。特别是第一步,可能第一次安装的人都会感到奇怪,Maya的安装文件在那儿一动不动。:) 向这位博主表示感谢: http://hi.baidu.com/zlsober/blog/item/e606c6136b3afc075baf5378.html 1.安装...