12生成器、列表推导式

一、生成器

  1. 生成器本质就是迭代器,唯一的区别就是,生成器是我们自己用代码构建的数据结构。迭代器都是系统提供或者是转化而来的。

  2. 获取生成器的三种方式

    • 生成器函数
    • 生成器表达式
    • python内部提供的
  3. 生成器的特点、优缺点和迭代器都是一样的

  4. 生成器函数

    def func():
        yield 3
        yield 4
    ret = func()
    print(next(ret))
    print(next(ret))
    # 结果如下:
    3
    4
    
    • 一个next就对应一个yield
    • return和yield的区别
      • return:函数中只有一个return起作用,并且给函数返回一个值
      • yield:只要函数中有yield,这个函数就是一个生成器函数,不是普通的函数,一个yield对应一个next,yield不会结束函数。
  5. 生成器作用

    • 虽然迭代器可以节约内存,但是如果列表中有一亿个数据,还没等转换成迭代器,内存已经撑爆了。

    • 生成器是自己用python代码构建的

    • 假如想产生5000个数据放在列表中

      #方法一:用函数生成
      def func():
          li=[]
          for i in range(1,5001):
              li.append(i)
          return li
      ret=func()
      print(ret)
      # 把5000个元素一次性放在列表中,占用内存
      
      #方法二:用生成器生成
      def gen_func():
          for i in range(1,5001):
              yield i
      ret=gen_func()
      for i in range(200):
          print(next(ret))
      #结果,虽然生成了5000个元素,但是现在是用一个取一个,节约内存空间。
      
  6. yield from

    • 可以将一个列表变成迭代器

      def func():
          li=[1,2,3,4,5]
          yield from li
      ret=func()
      print(next(ret))
      # 结果如下:
      1
      
      • 加一个from就是把列表所有元素拆开

二、列表推导式

  1. 定义:

    • 用一行代码,构建一个比较复杂且有规律的列表。
  2. 传统生成列表的方式

    • 手动输入

      lis=[1,2,3,4,5,6,7,8,9,10]
      
      • 如果元素很少,可以这样,如果元素很多不方便。
    • 用for循环生成

      lis=[]
      for i in range(1,11):
          lis.append(i)
      
      • 用for循环可以自动达到效果,但是代表比较多
  3. 用列表推导式生成列表

    lis=[i for i in range(1,101)]
    print(lis)
    
  4. 列表推导式几种模式

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

    • 练习1:将10以内所有整数的平方写入列表

      lis=[i**2 for i in range(1,11)]
      print(lis)
      
    • 练习2:将100以内所有偶数写入列表

      lis=[i for i in range(2,101,2)]
      print(lis)
      
    • 练习3:把python1期到python100期写入列表lis

      #lis=[f"python{i}期" for i in range(1,101)]
      lis=["python{}期".format(i) for i in range(1,101)]
      print(lis)
      
  6. 筛选模式

    • 练习1:30以内能被3整除的数

      print([i for i in range(1,31) if i%3==0])
      
    • 练习2:过滤掉长度小于3的字符串列表,并将剩下的转换成大写字母

      l1=["python",'java','c++','shell','c']
      print([i.upper() for i in l1 if len(i) >= 3])
      
    • 练习3:找到names列表中,名字含有两个'e'的所有名字

      names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],
               ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
      print([name for lis in names for name in lis if name.count("e")==2])
      

三、生成器表达器

  1. 生成器表达式

    • 和列表推导式使用方法一模一样
    • 唯一区别就是,生成器表达式用()表示,列表推导式用[]表示
  2. 练习

    • 生成一个1-100偶数的生成器

      gen=(i for i in range(2,101,2))
      gen=(i for i in range(2,101,2))
      for i in range(100):
          try:
              print(next(gen))
          except StopIteration:
              break
      

四、总结

  1. 推导式缺点
    • 列表推导式只能构建比较复杂且有规律的列表
    • 如果超过三层循环才能构建成功,就不建议使用列表推导式
    • 开启debug模式查找错误不方便,不会把内部执行结果一步一步显示出
  2. 推导式优点
  • 一行构建,代码简洁
  1. 构建列表:2,3,4,5,6,7,8,9,10,'j','Q','K','A'

    li=[ i for i in range(2,11)]+list("JQKA")
    print(li)
    
  2. 列表推导式与生成器表达式区别

    • 写法上不同,一个是[]符号,一个是()符号
    • 本质上不一样。列表推导式是一个可迭代对象,生成器表达式是一个迭代器

五、字典推导式

  1. 使用方法

    list_key=["name","age","sex","job"]
    list_value=['jack',18,'男','运维']
    dic={list_key[i]:list_value[i] for i in range(len(list_value))}
    print(dic)
    #结果如下:
    {'name': 'jack', 'age': 18, 'sex': '男', 'job': '运维'}
    
posted @ 2023-07-12 09:46  majic_jie  阅读(64)  评论(0)    收藏  举报