python生成器、推导式及匿名函数

  1. 生成器初识

    生成器本质就是迭代器。python社区中生成器与迭代器是一种概念。生成器与迭代器的唯一区别:迭代器都是Python给你提供的已经写好的工具或者通过数据转化得来的,(比如文件句柄,iter([1,2,3])。生成器是我们自己用python代码构建的工具。

  2. 生成器构建方式

    1. 生成器函数。
    2. 生成器表达式。
    3. python给你提供的一些内置函数,返回一个生成器。
  3. 生成器函数。

    生成器函数: 只要函数中出现了yield那么他就不是函数,它是生成器函数

    def func():
        print(111)
        yield 2,4,5    
        print(222)
        yield 3
    ret = func()  # 生成器对象
    print(ret)  # <generator object func at 0x0000000001E10F68>
    # 只要函数中出现了yield那么他就不是函数,它是生成器函数。
    # 一个next对应一个yield.next超过yield数量,就会报错,与迭代器一样。
    print(next(ret))
    print(next(ret))
  4. yiled与return的区别

    # return 结束函数,给函数的执行者返回值(多个值通过元组的形式返回)。
    # yield  不结束函数,对应着给next返回值(多个值通过元组的形式返回)。
  5. send(了解)

    def gen(name):
        print(f'{name} ready to eat')
        while 1:
            food = yield 222
            print(f'{name} start to eat {food}')
    dog = gen('alex')
    next(dog)  # 第一次必须用next让指针停留在第一个yield后面
    # 与next一样,可以获取到yield的值
    ret = dog.send('骨头')
    print(ret)
    
    def gen(name):
        print(f'{name} ready to eat')
        while 1:
            food = yield
            print(f'{name} start to eat {food}')
    dog = gen('alex')
    next(dog)
    # 还可以给上一个yield发送值
    dog.send('骨头')
    dog.send('狗粮')
    dog.send('香肠')
    
    send和next()区别:
    相同点:
    send 和 next()都可以让生成器对应的yield向下执行一次。
    都可以获取到yield生成的值。
    不同点:
    第一次获取yield值只能用next不能用send(可以send(None))。
    send可以给上一个yield置传递值。
  6. yiled与yiled from。

    # yield from 的作用
    def func():
        l1 = [1, 2, 3]
        yield from l1
        '''
        yield 1
        yield 2
        yield 3
        '''
    ret = func()
    print(next(ret))
    print(next(ret))
    print(next(ret))
    # yield : 对应next给next返回值
    # yield from 将一个可迭代对象的每一个元素返回给next
    # yield from 节省代码,提升效率(代替了for循环)
  7. 列表推导式,生成器表达式(字典推导式,集合推导式)。

    列表推导式:一行代码构建一个有规律比较复杂的列表。

    列表推导式与之前写法对比

    l1 = []
    for i in range(1,101):
        l1.append(i)
    print(l1)
    # 列表推导式
    l1 = [i for i in range(1, 101)]
    print(l1)

    两种构建方式:

    1.循环模式: [变量(加工后的变量) for 变量 in iterable]

    2.筛选模式: [变量(加工后的变量) for 变量 in iterable if 条件]

    循环模式:

    # 循环模式:
    # 将10以内所有整数的平方写入列表。
    print([i**2 for i in range(1, 11)])
    # 100以内所有的偶数写入列表.
    print([i for i in range(2, 101, 2)])
    # 从python1期到python100期写入列表list
    print([f'python{i}期' for i in range(1, 101)])

    筛选模式:

    # 1-100里大于49的数
    print([i for i in range(1, 101) if i > 49])
    # 三十以内可以被三整除的数。
    print([i for i in range(1, 31) if i % 3 == 0])
    # 过滤掉长度小于3的字符串列表,并将剩下的转换成大写字母
    l1 = ['barry', 'fdsaf', 'alex', 'sb', 'ab']
    print([i.upper() for i in l1 if len(i) > 3])
    # 找到嵌套列表中名字含有两个‘e’的所有名字(有难度)
    names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
    l1 = []
    for i in names:
        for j in i:
            if j.count('e') > 1:
                l1.append(j)
    print(l1)
    # 列表推导式
    print([j for i in names for j in i if j.count('e') > 1])

    列表推导式的优缺点

    列表推导式的优缺点:
    优点:
       简单,快捷,装b。
    缺点:
       可读性不高,不好排错。
    # 慎用,不要入迷。

    生成器表达式

    与列表推导式几乎一模一样。

    循环模式,筛选模式。

    obj = (i for i in range(1, 11))
    # 把中括号换成小括号解释生成器表达式

    如何触发生成器(迭代器)取值?

    1. next(obj)
    2. for 循环
    for i in obj:
        print(i)
    3. 数据转化
    print(list(obj))
    # 生成器表达式:生成器 节省内存。

    字典推导式,集合推导式

    # 字典推导式,集合推导式:  两种模式: 循环模式,筛选模式
    l1 = ['小潘', '怼怼哥','西门大官人', '小泽ml亚']
    # {0: '小潘', 1: '怼怼哥', 2: '西门大官人'}
    dic = {}
    for index in range(len(l1)):
        dic[index] = l1[index]
    print(dic) 
    # 字典推导式
    print({i:l1[i] for i in range(len(l1))})
    # 集合推导式生成 1~100的集合
    print({i for i in range(1, 101)})
  8. 匿名函数。

    # 匿名函数:没有名字的函数
    # 匿名函数只能构建简单的函数,一句话函数。
    def func(x,y):
        return x + y
    print(func(1, 2)) # 3
    # 匿名函数构建
    func2 = lambda x,y: x + y
    print(func2(1, 2)) # 3
    # 匿名函数最常用的就是与内置函数结合使用。
    # 写匿名函数:接收一个可切片的数据,返回索引为 0与2的对应的元素(元组形式)。
    func = lambda x: (x[0],x[2])
    print(func('太白金星')) # ['太','金']
    # 写匿名函数:接收两个int参数,将较大的数据返回。
    func1 = lambda x, y: x if x > y else y
    print(func1(100,2)) # 100
    
    func2 = lambda : 3
    print(func2()) # 3

猜你喜欢

转载自www.cnblogs.com/changyifei-8/p/11061386.html