• 函数进阶3 —— 生成器、yield from


    今天我们在进一步了解一下,生成器。

    ①:

    1 def func():
    2     print('这是函数func')
    3     return '函数func'
    4 func()

    结果是 

    这是函数func

    ②:

    1 def func1():
    2     print('这是函数func1')
    3     yield '函数func'
    4 func1()

    ③:

    1 def func1():
    2     print('这是函数func1')
    3     yield '函数func'
    4 print(func1())

    结果: 

    <generator object func1 at 0x0000000002138E58>  返回的是func1的内存地址。

    有没有发现这三个的值不一样。

    那么 return 和yield 的区别是什么呢?

    return是返回值,直接停止这个函数,

    yield是分段停止这个函数。

    1.生成器的本质就是迭代器
    2.通过函数变成一个生成器
     1 def func():
     2     print(1)
     3     yield 5  # 我的函数走到这了
     4     print(2)
     5     yield 9  # 我的函数走到这了
     6 
     7 g = func()  # 生成一个生成器
     8 
     9 print(g.__next__())
    10 print(g.__next__())
    
    
    def func():
        print(1)
        # return 5
        yield 5
    print(func().__next__())  # 这样生成一个生成器
    print(func().__next__())  # 这样生成一个生成器
    print(func().__next__())  # 这样生成一个生成器
    print(func().__next__())  # 这样生成一个生成器
    
    
    

      

     1 def func():
     2     print(1)
     3     yield 5  # 我的函数走到这了
     4     print(2)
     5     yield 9  # 我的函数走到这了
     6 
     7 g = func()  # 生成一个生成器
     8 print(g.__next__())
     9 print(g.__next__())
    10 
    11 碰到return就结束函数
    12 碰到yield不结束就挂起
    13 生成器的好处,非常节省内存
    
    
    def func():
        print(1)
        a = yield 2  # 1.挂起 2.返回值 3.接受值
        print(a)   # '123'
        print(3)
        b = yield 4
        print(b)   #'234'
        c = yield 9
    g = func()
    
    print(g.__next__())   #1 2  g.send(None)
    print(g.send('123'))  # send = next+传值
    print(g.send('234'))  # send = next+传值
    # 第一次调用生成器的时候使用send里边的值必须是None
    
    
    1 def func():
    2     yield 1
    3     yield 2
    4 
    5 g = func()
    6 ret = g.__next__()
    7 print(ret+4)
    8 print(g.__next__())

    2.yield  from

     1 def func():
     2     li = [1,2,3,4]
     3     # yield li
     4     yield from li  #(= for yield in li)
     5 
     6 ret = func()  # 把生成器的地址给了ret
     7 print('is ret',ret.__next__())  #一个生成器
     8 print('is ret',ret.__next__())
     9 # 执行ret这个变量的指向的生成器地址:
    10 print('is ret',ret)
    11 # # 在全局空间找到一个变量叫做ret的,打印它的值 值就是生成器的地址
     1 def func():
     2     li = [1,2,3,4]
     3     l2 = [5,6,7,8]
     4     # yield from li
     5     # yield from l2
     6     for i in li:
     7         yield i
     8 
     9     for em in l2:
    10         yield em
    11 #
    12 ret = func()  # 把生成器的地址给了ret
    13 print('is ret',ret.__next__())
    14 print('is ret',ret.__next__())
    15 print('is ret',ret.__next__())
    16 print('is ret',ret.__next__())
    17 print('is ret',ret.__next__())
    yield from li  =  for i in li
               yield i 

     1 # 总结:
     2 #     1.生成器的本质就是一个迭代器
     3 #     2.生成器一定是一个迭代器,迭代器不一定是一个生成器
     4 #     3.生成器是可以让程序员自己定义的一个迭代器
     5 #     4.生成器的好处,节省内存空间
     6 #     5.生成器的特性 一次性的,惰性机制,从上向下
     7 #     6.send相当于 next+传值,第一次触生成器的时候,如果使用send(None)
     8 #         值必须是None,一般我建议你们使用__next__
     9 #     7.    python2 iter()  next()
    10 #           python3 iter()  next()  __next__() __iter__()
    11 #     8.yield from 将可迭代对象元素逐个返回
    
    

    3.推导式

    一个容器包在最外面,结果,语法:

    [结果,语法] #容器

    1 # 列表推导式
    2 li = []
    3 for i in range(10):
    4     li.append(i)
    5 print(li)
    6 
    7 print([i for i in range(10)])
    
    
    1 li = []
    2 for i in range(10):
    3     if i%2 == 1:
    4         li.append(i)
    5 print(li)
    6 
    7 print([i for i in range(10) if i%2 == 0])  # 过滤(筛选)
    
    

    for循环的嵌套:

    1 li = []
    2 for i in range(3):
    3     for em in range(3):
    4         li.append(em)
    5 print(li)
    6 
    7 # print([j for i in range(10) for em in range(3) for j in range(5)])

    其字典、集合的推导式同列表推导式,没有元组推导式。

    
    
    1 g = (i for i in range(10))
    2 print(g)
    3 
    4 结果:<generator object <genexpr> at 0x0000000002168E58>
    
    
    
     
  • 相关阅读:
    命令实现linux和客户端文件上传下载
    python--linux上如何执行shell命令
    Eureka系列(一)Eureka功能介绍
    Eureka系列(七) 服务下线Server端具体实现
    编译时多态 与 运行时多态
    静态绑定(前期绑定) 与 动态绑定(后期绑定)
    重载 与 重写
    热点检测、方法内联、动态反优化
    数据库日志
    单例模式
  • 原文地址:https://www.cnblogs.com/chitangyuanlai/p/10542045.html
Copyright © 2020-2023  润新知