• 生成器,推导式


    一.生成器:

    生成器的实质就是迭代器

    在python中有三种方式获取生成器:

    1.通过生成器函数

    2.通过各种推导式来实现生成器

    3.通过数据的转换也可以获取生成器

    二.通过生成器函数获取生成器:

    def func():
        print('哈哈')
        yield '呵呵'   #有yield就是生成器
    ret = func() #通过函数来创建一个生成器即生成器函数被执行,获取的是生成器,而不是函数的执行
    print(ret) #返回的值是个地址就是个生成器
    结果:<generator object func at 0x0000000000B99D00>

    就是将函数中的return换成yield就是生成器,

    return:直接返回结果,结束函数的调用

    yield:返回结果,可以让函数分段执行.

    1.如何执行生成器:

    1)生成器的本质就是迭代器,所以可以用__next__()进行执行

    def func():
        print('周杰伦')
        yield '昆凌'
        print('哈哈')
        yield '呵呵'
    ret = func()
    print(ret.__next__())
    print(ret.__next__())
    结果:周杰伦
        昆凌
        哈哈
        呵呵

    注意:如果最后一个yield执行完毕,再次__next__()程序会报错

    生成器的作用:省内存,可以一次去一个,一个个的指向下一个,不会回去,__next__()到哪,指针就指哪,下一次继续获取指针指向的值.

    2.用send()方法:

    def eat():
        print('我吃什么')
        a = yield '馒头'
        print('a=',a)
        b = yield'大饼'
        print('b=',b)
        c = yield'韭菜盒子'              
        print('c=',c)
        yield 'GAME OVER'
    gen = eat() #获取生成器
    print(gen.__next__())
    print(gen.send('胡辣汤'))
    print(gen.send('狗粮'))
    print(gen.send('猫粮'))
    结果:我吃什么
    馒头
    a= 胡辣汤
    大饼
    b= 狗粮
    韭菜盒子
    c= 猫粮
    GAME OVER

    send 和 __next__区别
    1).send和next()都是让生成器向下走一次

    2).send可以给上一个yield的位置传递值,不能给最后一个yield发送值,第一次执行生成器代码的时候不能使用send()

    3.生成器本质上是迭代器,所以可以使用for循环取值

    def func():
        print('哈哈')
        yield '呵呵'
        print('嘿嘿')
        yield '嘻嘻'
        print('呀呀')
        yield'花花'
    ret = func()
    for i in ret:
        print(i)

    4.可以用列表list取值:

    def func():
        print('哈哈')
        yield '呵呵'
        print('嘿嘿')
        yield '嘻嘻'
        print('呀呀')
        yield'花花'
    ret = func()
    print(list(ret))
    结果:哈哈
        嘿嘿
        呀呀
    ['呵呵', '嘻嘻', '花花']

    三.列表推导式,生成器表达式以及其他推导式

    1)列表推导式:[结果 for 变量 in 可迭代对象 if 筛选]

    例:给一个列表,通过循环,向列表中添加1-9

    lst = []
    for i in range(1,10)
        lst.append(i)
    print(lst)

    通过列表推导式:

    lst = [i = for i in range(1,10)]
    print(lst)

    对列表中的数据进行筛选:[结果 for 变量 in 可迭代对象 if条件]

    lst = [i fro i in range(1,101) if i%2 == 0]
    print(lst)

    2)生成器表达式:

    生成器表达式和列表推导式的语法基本上一样,只是把[]替换()

    gen = (i for i in range(100))
    print(gen)
    结果:<generator object <genexpr> at 0x0000000000A29D00>

    打印结果是个生成器,可以用for循环来获取最终结果

    gen = (i for i in range(100))
    for i in gen:
        print(i)

    生成器表达式也可以进行筛选,跟列表表达式一样,只是[]变成了()

    生成器表达式和列表推导式的区别:

    1.列表推导式比较耗内存,一次性加载,生成器表达式几乎不占内存,使用的时候才分配和使用内存.

    2.得到的值不一样,列表推导式得到的是一个列表,生成器表达式获取的是一个生成器

    生成器的惰性机制:生成器只有在访问的时候才取值,说白了,你找他要他才给你值,不找他要,他就不回执行.

    def func():
        print(111)
        yield 222
    g = func() # 生成器g
    g1 = (i for i in g) # 生成器g1. 但是g1的数据来源于g
    g2 = (i for i in g1) # 生成器g2. 来源g1
    print(list(g)) # 获取g中的数据. 这时func()才会被执行. 打印111.获取到222. g完毕.
    print(list(g1)) # 获取g1中的数据. g1的数据来源是g. 但是g已经取完了. g1 也就没有数据了
    print(list(g2)) # 和g1同理

    神坑:生成器,要值的时候才拿值

    3)字典推导式{结果 for 变量 in可迭代对象 if 筛选} 结果--->key:value

    dic = {'a':'b','c':'d'}

    把字典中的key和value互换

    dic = {"a":"b", "c":"d"}
    new_dic = {dic[key]:key for key in dic }
    print(new_dic)
    

    4)集合推导式:{结果 for 变量 in 可迭代对象 if 筛选}  结果--->key

    集合推导式可以直接生成一个集合,集合特别,无序,不重复,所以集合推导式自带去重功能

    lst = ["马化腾", "马化腾", "王建忠", "张建忠", "张建忠", "张雪峰", "张雪峰"]
    s = {i for i in lst}    # 集合推倒式
    print(s)

    总结:推导式有:列表推导式,字典推导式,集合推导式,没有元祖推导式

      生成器表达式:(结果 for 变量 in 可迭代对象 if 筛选)

      生成器表达式可以直接获取到生成器对象,生成器可以直接进行for循环,生成器具有惰性机制

  • 相关阅读:
    android ksoap2 访问webservice,连续两次调用时,第二次调用异常(转)
    iOS Programming – 触摸事件处理 (转)
    iPhone的解锁、越狱、激活、固件等等是什么意思,有什么分别?(转)
    pb中 执行动态sql
    Java的中文字体
    fastreport一些使用方法
    网页数据抓取
    base64
    TSelect
    解决DLL包组织的项目运行报 a class named Txxx exists
  • 原文地址:https://www.cnblogs.com/ITdong-1/p/9329808.html
Copyright © 2020-2023  润新知