zoukankan      html  css  js  c++  java
  • python函数-生成器

    1.理论知识:什么是生成器?

    生成器的本质就是迭代器。生成器和迭代器也有不同,唯一的不同就是:迭代器都是Python给你提供的已经写好的工具或者通过数据转化得来的,(比如文件句柄,iter([1,2,3])。生成器是需要我们自己用python代码构建的工具。最大的区别也就如此了。

    2.生成器的构建方式?

    在python中有三种方式来创建生成器:

      1. 通过生成器函数

      2. 通过生成器推导式

      3. python内置函数或者模块提供(其实1,3两种本质上差不多,都是通过函数的形式生成,只不过1是自己写的生成器函数,3是python提供的生成器函数而已)

    2.1)通过生成器函数构建生成器

    #普通函数
    def func():
        print(11)
        return 22
    ret=func()
    print(ret)
    
    #将函数中return换成yield,这样func就不是函数了。而是一个生成器函数
    def func():
        print(11)
        yield 22
    ret=func()
    print(ret)

    运行结果:

    #普通函数运行结果
    11 22
    #生成器函数运行结果 <generator object func at 0x02D9EE30>

    由于函数中存在yield,那么这个函数就是一个生成器函数.在执行这个函数的时候.就不再是函数的执行了.而是获取这个生成器对象

    2.2)生成器函数如何取值

    生成器的本质就是迭代器.迭代器如何取值,生成器就如何取值。所以我们可以直接执行next()来执行以下生成器

    def func():
        print('111')
        yield 222
    genner=func() # 这个时候函数不会执⾏. ⽽是获取到⽣成器
    ret=genner.__next__() print(ret) # 这个时候函数才会执⾏
     运行结果:
    111
    222
    def func():
        print("111")
        yield 222
        print("333")
        yield 444
    gener = func()
    ret = gener.__next__()
    print(ret)
    ret2 = gener.__next__()
    
    print(ret2)
    #ret3 = gener.__next__()
    # 最后⼀个yield执⾏完毕. 再次__next__()程序报错
    #print(ret3)
    
    运行结果:
    111
    222
    333
    444
    
    Process finished with exit code 0

    当程序运行完最后一个yield,那么后面继续运行next()程序会报错,一个yield对应一个next,next超过yield数量,就会报错,与迭代器一样。

     yield与return的区别:

            return一般在函数中只设置一个,他的作用是终止函数,并且给函数的执行者返回值。

            yield在生成器函数中可设置多个,他并不会终止函数,next会获取对应yield生成的元素。

    #return
    def
    eat(): lst = [] for i in range(1,10000): lst.append('包子'+str(i)) return lst e = eat() print(e) #yield def eat(): for i in range(1,10000): yield '包子'+str(i) e=eat() for i in range(200): a=next(e) print(a) for i in range(300): b=next(e) print(b)

    运行结果:

    return生成列表

    yield生成的是值,而且还可以保留上次的位置。暂用空间更小

     yield from函数

    # 对比yield 与 yield from 
    def func():
        lst = ['卫龙','老冰棍','北冰洋','牛羊配']
        yield lst
    g = func()
    print(g)
    print(next(g))  # 只是返回一个列表
    def func():
        lst = ['卫龙','老冰棍','北冰洋','牛羊配']
        yield from lst
    g = func()
    print(g)
    # 他会将这个可迭代对象(列表)的每个元素当成迭代器的每个结果进行返回。
    print(next(g))
    print(next(g))
    print(next(g))
    print(next(g))
    '''
    yield from ['卫龙','老冰棍','北冰洋','牛羊配'] 
    等同于:
        yield '卫龙'
        yield '老冰棍'
        yield '北冰洋'
        yield '牛羊配'
    '''

    yield from 是将列表中的每一个元素返回,所以 如果写两个yield from 并不会产生交替的效果

    def func():
        lst1 = ['卫龙','老冰棍','北冰洋','牛羊配']
        lst2 = ['馒头','花卷','豆包','大饼']
        yield from lst1
        yield from lst2
        
    g = func()
    for i in g:
        print(i)
  • 相关阅读:
    Delphi中动态创建的Panel无法改变颜色的解决办法(要把Panel的ParentBackground设为False)
    判断当前进程是否以管理员权限启动的
    在一个exe文件中查找指定内容,找到则返回起始位置, 否则返回0
    [置顶] 使用严苛模式打破Android4.0以上平台应用中UI主线程的“独断专行”
    删除IE缓存中指定的文件
    将窗体显示在 PageControl 上
    判断操作系统多久没有任何操作
    UrlDownloadFile, 线程下载文件, 带进度条
    用JSON 和 Google 实现全文翻译
    成为高效程序员的7个重要习惯
  • 原文地址:https://www.cnblogs.com/bashliuhe/p/13201039.html
Copyright © 2011-2022 走看看