zoukankan      html  css  js  c++  java
  • 生成器和生成器表达式

    一 . 生成器

      生成器就是迭代器

      生成器的特点和迭代器一样.

        1.省内存

        2.惰性机制

        3.只能向前

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

        1.通过生成器函数

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

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

      简单的生成器函数

    def func():    
        print("111")    
        yield 222 
    
    ret = func() 
    print(ret) 
    
    结果: 
    <generator object func at 0x10567ff68>

       yield和return的效果是一样的.  有什么区别呢?  yield是分段来执行一个 函数. return呢? 直接停止执行函数. 

    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__()程序报错, 也就是 说. 和return无关了了. 
    print(ret3) 
    
    结果: 111 
    Traceback (most recent call last): 
    222 
    333  
    File "/Users/sylar/PycharmProjects/oldboy/iterator.py", line 55, in <module> 
    444    
        ret3 = gener.__next__()  # 最后⼀一个yield执行完毕. 再次__next__()程序报错, 也 就是说. 和return无关了了. StopIteration

      send和__next__()区别:

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

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

    生成器可以使用for循环来循环获取内部的元素

    def func():    
        print(111)    
        yield 222    
        print(333)    
        yield 444    
        print(555)    
        yield 666 
    
    gen = func() 
    for i in gen:    
        print(i) 
    
    结果: 
    111 
    222 
    333 
    444 
    555 
    666

    二 . 推导式

      列表推导式:

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

    列表推导式的常用写法:     

      [ 结果 for 变量 in 可迭代对象]

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

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

    生成器表达式也可以进行筛选: 

    # 获取1-100内能被3整除的数 
    gen = (i for i in range(1,100) if i % 3 == 0) 
    for num in gen:    
        print(num) 
    
    # 100以内能被3整除的数的平方 
    gen = (i * i for i in range(100) if i % 3 == 0) 
    for num in gen:    
        print(num) 
    
    # 寻找名字中带有两个e的人的名字 
    names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],          ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']] 
    
    # 不用推导式和表达式 
    result = [] 
    for first in names:    
        for name in first:        
            if name.count("e") >= 2:            
                result.append(name) 
    
    print(result) 
    
    # 推导式 
    gen = (name for first in names for name in first if name.count("e") >= 2) 
    for name in gen:    
        print(name)    

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

      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同理

      深坑==> 生成器. 要值得时候才拿值. 

    字典推导式: 

    # 把字典中的key和value互换 
    dic = {'a': 1, 'b': '2'} 
    new_dic = {dic[key]: key for key in dic} 
    print(new_dic) 
    
    # 在以下list中. 从lst1中获取的数据和lst2中相对应的位置的数据组成一个新字典 
    lst1 = ['jay', 'jj', 'sylar'] 
    lst2 = ['周杰伦', '林俊杰', '邱彦涛'] 
    dic = {lst1[i]: lst2[i] for i in range(len(lst1))} 
    print(dic)

    集合推导式:

    lst = [1, -1, 8, -8, 12] 
    # 绝对值去重 
    
    s = {abs(i) for i in lst} 
    print(s)

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

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

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

    def add(a, b):    
        return a + b
    
    def test():    
        for r_i in range(4):        
            yield r_i
    
    g = test()  
    
    for n in [2, 10]:    
        g = (add(n, i) for i in g)
    
    print(list(g))
    
    结果:
    [20,21,22,23]

       友情提示: 惰性机制, 不到后不会拿值

      这个题要先读一下. 然后自己分析出结果. 后用机器跑一下. 

  • 相关阅读:
    uboot主Makefile之1——HOSTARCH&HOSTOS
    uboot主Makefile之3——BUILD_DIR(Line 78-93)
    Makefile的ifeq逻辑或,逻辑与的变通实现
    uboot主Makefile解析第二篇
    uboot主Makefile解析第一篇
    mkdir -p X 中的“-p”是的意思
    uboot主Makefile中的origin函数
    原生javascript实现call、apply和bind的方法
    js如何判断数组是Array类型
    三栏布局的5种解决方案及优缺点
  • 原文地址:https://www.cnblogs.com/xiangweilai/p/9468386.html
Copyright © 2011-2022 走看看