函数三生成器

一、生成器

  1. 定义

    ​ 生成器的本质就是迭代器,在python社区中,大多数时候都把迭代器和生成器是做同一个概念。生成器与迭代器的唯一区别:生成器是我们自己用python代码构建的。

  2. 构建方式

    • 通过生成器函数
    • 通过生成器推导式
    • 利用python内置函数或模块,返回一个生成器
  3. 生成器函数

    ​ 只要函数中出现了yield那么它就不是函数,而是生成器了,可通过next()取值,一个next()对应一个yield。

    def func():
        yield 2,4,5
        yield 3
        yield 4
        yield 5
    ret = func()  # 生成器对象
    print(ret)  # <generator object func at 0x0000000001E10F68>
    
  4. 生成器每次next()完都会停在当前的yield之后,下次执行时直接在本次的基础上执行

    def eat_baozi():
        for i in range(1,2001):
            yield f'{i}号包子'
    ret = eat_baozi()
    ret1 = eat_baozi()
    print(ret)#<generator object eat_baozi at 0x0000016EB6D34E60>
    print(ret1)#<generator object eat_baozi at 0x0000016EB6D34EB8>
    #从上边可以看出ret和ret1内存地址是不一样的,因此不能对生成器直接进行迭代取值,否则每次都是从一个新的生成器取值
    
    def eat_baozi():
        for i in range(1,2001):
            yield f'{i}号包子'
    ret = eat_baozi_gen()
    for i in range(200):
        print(next(ret))#1.....200
    for i in range(200):
        print(next(ret))#201...400
    
  5. yield与return的区别

    return 结束函数,给函数的执行者返回值(多个值通过元组的形式返回)。

    yield 不结束函数,对应着给next返回值(多个值通过元组的形式返回)。

  6. yiled与yiled form

    yield : 对应next给next返回值
    yield from 将一个可迭代对象的每一个元素返回给next, 节省代码,提升效率(代替了for循环)

    def func():
        l1 = [1, 2, 3]
        yield from l1
    ret = func()
    print(next(ret))	#1
    print(next(ret))	#2
    print(next(ret))	#3
    
  7. 列表推导式

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

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

      #之前写法:
      l1 = []
      for i in range(1,11):
          l1.append(i)
      print(l1)	#[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
      #列表推导式:
      print([i for i in range(1,11)])	#[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
      
    • 两种构建的方式:

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

        #将10以内的所有整数的平方写入列表:
        print([i*i for i in range(1,11)])
        #[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
        # 100以内所有的偶数写入列表.
        print([i for i in range(2, 101, 2)])
        # [2, 4, 6, .... 98, 100]
        
      2. 筛选模式: [变量(加工后的变量) for 变量 in iterable if 条件]

        # 三十以内可以被三整除的数
        print([i for i in range(1,31) if i%3 ==0])
        # [3, 6, 9, 12, 15, 18, 21, 24, 27, 30]
        
        # 找到嵌套列表中名字含有两个‘e’的所有名字(有难度)
        names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],
                 ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
        print([j for i in names for j in i if j.count('e') > 1])
        # ['Jefferson', 'Wesley', 'Steven', 'Jennifer']
        
    • 列表推导式的优缺点

      优点:简单,快捷,装逼

      缺点:可读性不高,不好排错

    • 字典推导式

      目前的几种字典定义方式:
      1.直接定义一个字典
      dic = {1:'盖伦',2:'德邦',3:'皇子',4:'剑圣'}
      2.formkeys方法
      dic = {}
      print(dic.fromkeys([1,2,3,4],'盖伦'))
      # {1: '盖伦', 2: '盖伦', 3: '盖伦', 4: '盖伦'}
      3.dict()函数
      print(dict(one='盖伦',two='德邦',three='皇子',four='剑圣'))
      # {'one': '盖伦', 'two': '德邦', 'three': '皇子', 'four': '剑圣'}
      4.字典推导式
      li = ['盖伦', '德邦', '皇子', '剑圣']
      print({i:li[i] for i in range(len(li))})
      # {0: '盖伦', 1: '德邦', 2: '皇子', 3: '剑圣'}
      
    • 集合推导式

      # 1~11
      print({i for i in range(1, 11)})
      # {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
      
原文地址:https://www.cnblogs.com/yaoqi17/p/11061634.html