• python第三十五课——生成器



    1.生成器:

    什么是生成器?

    它内部封装了一套公式/算法,只有等到需要调用/执行数据时 --> next()函数执行

    才会将公式计算得到数据结果,这就是生成器的原理(核心思想);

    【注意事项】:

    1).生成器中是没有真实数据存在,所以我们是不能直接使用len()函数来尝试得到其长度

    如果我们这么做了,会报错:StopIteration

    2).生成器中关联的真实数据只能被使用一次,不可逆

    格式:两种

    执行返回一个generator类型对象

    1).

    (条件表达式 for 参数列表 in 容器对象)

    2).

    定义函数,在函数的内部需要使用yield关键字来记录返回的generator对象的数据公式,

    【注意】函数此时如果有return,已经无视了/没有作用了,返回的一定是generator


    演示生成器的定义和使用:
    #格式1:(条件表达式 for 参数列表 in 容器对象)
    gen=(x for x in range(5))
    print(gen,type(gen))
    
    #generator对象不能配合len()来获取其长度
    print(len(gen))
    
    #使用next()函数来得到每一次genexpr中的内容
    print(next(gen))
    print(next(gen))
    print(next(gen))
    print(next(gen))
    print(next(gen))
    
    #generator对象中的数据内容只能被解析使用一次,不可逆;一旦调用多了,直接报错;
    # StopIteration
    print(next(gen))

    以下是两种解析处理generator对象的方式:
    方式一:使用next()函数调用,如果调多了,报错:StopIteration
    方式二:使用循环处理,如果调多了,不会报错,什么都看不到-->这样的方式更加友好
    print(next(gen))
    print(next(gen))
    for g in gen:
        print('11111')
        print(g)
        print(next(g))
        print('*'*50)
    
    for g in gen:
        print(g)


    需求:思考如果对于gen对象中的真实数据我需要用到多次,那怎么办?
    可以将generator对象gen转换为一个譬如list对象即可
    gen=(x for x in range(5))
    lt=list(gen)
    print(lt,type(lt))
    
    for i in lt:
        print(i)
        print('*'*50)
    
    i=0
    while i<len(lt):
        print(lt[i])
        i+=1

    格式2:
    定义函数,在函数的内部需要使用yield关键字来记录返回的generator对象的数据公式,
    【注意】函数此时如果有return,已经无视了/没有作用了,返回的一定是generator
    def func(n):
        lt=[]
        for i in range(1,n+1):
            if i%2==0:
                lt.append(i)
                yield i
        return lt
    
    f=func(10)
    print(f,type(f))
    
    print(len(f))
    print(next(f))
    
    for i in f:
        print(i)
    
    print(list(f))
    
    gen=(x for x in range(1,11) if x%2==0)
    for g in gen:
        print(g)

    需求:实现全排列
    str1='ABC'
    str2='XYZ'
    def func2(str1,str2):
        for s1 in str1:
            for s2 in str2:
                yield s1 + s2
    
    gen=func2(str1,str2)
    print(gen,type(gen))
    
    for g in gen:
        print(gen)
    
    print('*'*50)
    
    gen=(x+y for x in str1 for y in str2)
    for g in gen:
        print(g)

    比较:列表生成式和生成器?

    对于生成器而言:

    定义执行会得到一个generator对象,

    此对象中没有真实数据(第一手没值),它内部封装了一套公式/算法,

    一旦需要使用数据了,就会计算公式,得到内容;

    就因为这样的特点,所以我们得出结论:

    1).生成器比较节省内存资源(好处)

    2).在数据运算时比列表生成式效率要慢一点(弊端)

    对于列表生成式而言:

    定义执行会得到一个列表对象,

    在定义执行完毕后,列表中已经确定了真实的数据(进内存了)

    就因为这样的特点,所以我们得出结论:

    1).列表生成式比较占用内存资源(弊端)

    2).在数据运算时比生成器效率要快一点(好处)
  • 相关阅读:
    温故知新,.NET 重定向深度分析
    修复搜狗、360等浏览器不识别SameSite=None 引起的单点登录故障
    用机器学习打造聊天机器人(二) 概念篇
    用机器学习打造聊天机器人(一) 前言
    做为GPU服务器管理员,当其他用户需要执行某个要root权限的命令时,除了告诉他们root密码,还有没有别的办法?
    Viterbi(维特比)算法在CRF(条件随机场)中是如何起作用的?
    使用t-SNE做降维可视化
    用深度学习做命名实体识别(七)-CRF介绍
    用深度学习做命名实体识别(六)-BERT介绍
    BERT论文解读
  • 原文地址:https://www.cnblogs.com/hankleo/p/10453795.html
Copyright © 2020-2023  润新知