• 生成器/内置函数


    生成器

    本质就是迭代器,手动写的迭代器

    生成器函数

    def func():
        print (123)
        yield '生成器'
    func() ## 执行结果 :没有结果
    '''******'''
    ret = func() ## 这个过程相当于 实例化对象  
    '''******'''
    print(ret) #<generator object func at 0x000002A9298C3F48>生成器对象
    # 想执行这个 要用next() 和迭代器一样 或者遍历它
    next(ret) ## 123  
    print(next(ret)) ## 111 2 # 如果生成器中没有yield了,再调用next会报错
    

    生成器函数的坑(1)

    ## for循环中的生成器
    def add(n, i):
        return n+i
    
    def test():
        for i in range(4):
            yield i
    
    g = test()
    
    for n in [1, 10, 5]:
        g = (add(n, i) for i in g)
    
    print(list(g))  # 结果是 [15, 16, 17, 18] 
    ## 关键点在于生成器相当于函数,不调用就不执行,只有最后list(g)了,才一层一层的解开
    # for循环3次 相当于
    n = 1 
    g = ((n+i) for i in test())
    n = 10
    g = ((n+i) for i in g(此时的g是((n+i) for i in test()) ))
    n = 5
    g = ((n+i) for i in g(此时的g是 ((n+i) for i in ((n+i) for i in test()) )))
    
    list(g) 的时候才 开始执行这个表达式 此时n已经是 5 了
    ## 最后的结果也就是循环几层,取几次5,再与g的各项相加取值
    5*3+0,5*3+1,5*3+2,5*3+3
    
    

    生成器的坑(2)

    def demo():
        for i in range(4):
            yield i
    
    g=demo()
    
    g1=(i for i in g)
    g2=(i for i in g1)
    
    print(list(g1))## list(g1)相当于在底层for循环,也就是next(g1),到最后一层
    print(list(g2)) ## 所以当list(g2)时,for遍历g1,next(g1)指不到东西
    

    生成器的坑(3)

    v = (lambda :x for x in range(10))
    
    print(v)
    
    print(next(v))
    
    print(next(v)())
    
    ## 生成器地址
    ## 匿名函数地址
    ## 1   因为 生成器是next() 一次执行一次, 上一次next执行到 x = 1  所以这次执行匿名函数返回1(生成器表达式,next一次可以理解为里面的代码走一圈)
    ## 生成器 next执行一次   for 循环 执行到底   list() 执行到底
    

    yield

    阻塞

    return 和 yield

    ## return 结束函数,给函数的执行者返回值
    ## yield 不结束函数,给next(func()) 返回值
    

    yield from

    def func():
    	l = [1,2,3]
    	yield from l
    fun = func()
    print (next(fun)) # 1
    print (next(fun))# 2
    print (next(fun))# 3,
    ## 取代了for循环,将可迭代对象中的每一项元素依次取出来
    

    匿名函数

    lambda x,y:x+y
    不调用,不执行,不调用,不执行
    

    列表推导式 生成器表达式

    ## 列表推导式
    l = [i for i in iterable if i...]
    
    ## 一行代码实现九九乘法表
    '
    '.join([' '.join([f'{j}*{i}={j*i}'for j in range(1,i+1)]) for i in range(1,10)])
    
    # 生成器表达式
    obj = (i for i in iterable if i...)
    ## 取值方式
    # 第一种
    print(next(obj))
    # 第二种
    for i in obj:
        print(i)
    # 第三种
    print (list(obj))
    

    内置函数

    min

    # 参数列表可以放key的
    min()
    max()
    sorted()
    # 例如  min()
    dic = {'a':1,'b':2,'c':3,'d':0}
    print(min(dic)) # 此时返回的结果为 a
    print (min(dic,key=lambda x:x))  ## 相当于将dic遍历传入 lambda表达式(函数)中,return 的是什么就按照什么比较,这个x是dic的key,所以返回的也是字典的key 
    

    zip

    ## zip ## 将传入的可迭代对象,按相同索引组合成一个元组,直到其中一项到索引最后一项
    def zipp(*iterable):
        obj = object()
        iterators = [iter(it) for it in iterable]
        while iterators:
            result = []
            for it in iterators:
                em = next(it,obj)
                if em is obj:
                    return
                result.append(em)
            yield tuple(result)
    a = zipp('asd','zxc','qwe')
    
    while 1:
        try:
            print(next(a))
        except:
            break
            
    print(list(a)) # [('a', 'z', 'q'), ('s', 'x', 'w'), ('d', 'c', 'e')]
    ## 返回的是迭代器对象
    

    filter

    ## 过滤
    filter(func,lst)
    
    lst = [{'id':1,'name':'alex','age':18},
            {'id':1,'name':'wusir','age':17},
            {'id':1,'name':'taibai','age':16},]
     
    ls = filter(lambda e:e['age'] > 16,lst)
     
    print(list(ls))
     
    结果:
    [{'id': 1, 'name': 'alex', 'age': 18},
     {'id': 1, 'name': 'wusir', 'age': 17}]
    ## 返回的是迭代器对象
    
    

    map

    # map 映射函数
    lis = [1,2,3,4,5]
    for i in map(lambda x:x**2,lis):
        print(i)
    # 1,4,9,16,25
    
    lis1 = [1,2,3,4,5]
    m1 = map(lambda x,y:x+y,lis,lis2)
    for i in m1:
        print(i)  # 2,
        4,6,8,10
    ## 返回的是迭代器对象
    

    reduce

    ## 归并函数
    from functools import reduce
    l = [1,2,3,4]
    
    ret = reduce(lambda x,y:x*y,l)
    print(ret)
    ## 解决阶乘
    # 返回的是值
    
  • 相关阅读:
    SpringBoot项目设置maven打包时间
    SpringBoot热部署配置
    Git笔记
    SpringBoot LogBack日志配置
    CURL使用教程
    Linux 安装Docker及使用
    转发和重定向的区别
    16周作业
    16
    15周
  • 原文地址:https://www.cnblogs.com/albert0823/p/11060953.html
Copyright © 2020-2023  润新知