• 函数三生成器


    一、生成器

    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}
        
  • 相关阅读:
    空悬指针、野指针、内存泄漏、内存溢出
    自定义消息的操作方法ON_MESSAGE(..)
    为什么static成员变量一定要在类外初始化?
    Ubuntu 系统目录结构
    Beyond Compare 4 30天评估期结束的解决办法
    C++ string 字符串 结尾 标志
    C语言——枚举类型用法
    结构体struct-联合体union-枚举enum
    网卡bood
    kvm 安装
  • 原文地址:https://www.cnblogs.com/yaoqi17/p/11061634.html
Copyright © 2020-2023  润新知