zoukankan      html  css  js  c++  java
  • Python之函数(七)生成器与推导式

    生成器

    1. 简介:

      什么是生成器? 生成器的本质就是迭代器
      
      生成器跟迭代器的区别:迭代器都是python给你提供已经写好的工具或者数据转换而来的,生成器需要我们自己用python代码构建的工具
      
    2. 生成器的构建方式

      • 通过生成器函数

        • def func():
              print(11)
              return 22
          ret=func()
          print(ret)
          #结果为:11 22
          #将函数中的return换成yield,这样func就不是函数了,而是一个生成函数
          def func():
          	print(11)
              yield 22
          ret=func()
          print(ret)
          #运行结果:
          <generator object func at 0x000001A575163888>
          #当我们调用函数的时候函数体里的代码会进行执行当执行到yield的关键字的时候,发现我们是想声明一个生成器.程序就会返回一个生成器给咱们
          
        • 生成器取值

        • def func():
          	print("11")
          	yield 222
          gen=func()#这个时候函数不会执行,而是获取到生成器
          ret=gen.__next__()#这时候才会执行
          print(ret)#并且yield会将func生产出来的数据222 给了ret
          #结果:
          #11
          #222
          
        • 生成器可以写多个yield

        • def func():
          	if 3>2:
          		yield "你好"
          	if 5>4:
          		yield "我好"
          	yield "大家好"
          g=func()#产生一个生成器
          print(g.__next__())#获取到 "你好"赋值给g 并输出
          #结果为:"你好"
          for i in g:
          	print(i)
          #for循环将g里面的元素进行迭代输出
          #结果: 你好 我好 大家好
          
          #生成器的本质
          while True:
          	try:
          		print(g.__next__())
          	except StopIteration:
          		break
          
        • def foo():
              for i in range(10)#进行循环
              	pass#占位符 不执行
              	yield i# 执行
              count=0
              while True:
                  yield count
                  count+=1
          g=foo()#产生一个生成器
          print(next(g))#将0赋值给next 并输出 此时指针位置停留在 0
          #结果为:0
          for i in g:
              print(i)
          #循环输出g 生成器的元素
          
          #生成器应用场景
          def func():
              for i in range(100)
              	yield i
          g=func()
          for i in range(50):
              print(next(g))
          #输出50次 g生成器的元素
          
        • 总结:

        • yield与return的区别:
          在函数中将return改写成yield就是一个生成器
          yield会记录执行位置
          return和yield都是返回
          return可以写多个但是只执行一次,yield可以写多个,还可以返回多次
          一个 __next__()对应一个yield
          生成器可以使用for循环获取值
          
        • send()(备注:了解)

        • #next只能获取yield生成的值,但是不能传递值
          #使用send方法可以传递值
          def gen:
              while 1:
                  food=yield
                  print(f"sfd{food}")
          dog=gen()#获取生成器
          next(dog)#第一次必须用next让指针停留在第一个yield后面
          dog.send("骨头")#将值传递给上一个yield发送值
          
          #send和next()区别:
          #相同点:send和next()都可以让生成器对应的yield向下执行一次
          #都可以获取到yield生成的值
          
          #不同点:
          #第一次获取yield值只能用next不能用send(可以用send(None))
          #send可以给上一个yield传递值
          
        • yield from

        • #简介:在python3中提供一种可以直接把可迭代对象中的每一个数据作为生成器的结果进行返回
          #对比yield 和yield from
          def func():
          	lst=['卫龙','老冰棍','北冰洋','牛羊配']
              yield lst
          g=func()
          print(g)
          print(next(g))#只是返回一个列表
          
          def func():
              lst = ['卫龙','老冰棍','北冰洋','牛羊配']
              yield from lst
          g=func()
          print(g)#他会将这个可迭代对象每个元素当作迭代器的每个结果进行返回
          for x in g:
              print(x)
          #循环输出g生成器里的元素
          
          
          
        • yield from 小坑

        • def func():
              lst1 = ['卫龙', '老冰棍', '北冰洋', '牛羊配']
              lst2 = ['馒头', '花卷', '豆包', '大饼']
              yield from lst1
              yield from lst2
          
          
          g = func()
          for i in g:
              print(i)
          #返回的结果是将第一个列表的元素全部返回后,在返回第二个列表
          #产生两个新的生成器
          print(func().__next__())
          print(func().__next__())
          
        • 总结:

        • # 在函数中将return改写成yield就是一个生成器
          # yield 会记录执行位置
          # return 和 yield 都是返回,
          # return 可以写多个,但是只执行一次,yield可以写多个,还可以返回多次
          # 一个__next__() 对应 一个yield
          # 生成器可以使用for循环获取值
          # yield from -- 将可迭代对象元素逐个返回
          # 在函数的内部 yield 能将for循环和while循环进行临时暂停
          
      • 通过生成器推导式

      • #循环模式
        g=(i for i in range(20))
        for i in g:
            print(i)
        #筛选模式
        g=(i for i in range(50) if i %2==1)
        for i in g:
            print(i)
        
      • python内函数或者模块提供

    4.11 推导式

    1. list推导式

      lst=[]
      for i in range(3):
      	lst.append(i)
      print(lst)
      #结果为 [0,1,2]
      #推导式
      print([i for i in range(3)])
      #结果为[0,1,2]
      
    2. 循环模式

      • #[变量 for i in range(20)]
        print[i+1 for i in range(10)]
        
    3. 筛选模式

      • lst=[]
        for i in range(20):
        	if i%2==0:
        		lst.append(i)
        print(lst)
        
        print([i for i in range(20) if i%2 ==0])
        #[变量(加工后的变量)for循环 加工方式]
        
    4. 生成器表达式

      • 循环模式

        # g = (i for i in range(20))
        # print(next(g))
        # print(next(g))
        # print(next(g))
        
        # print(list((i for i in range(20))))
        
      • 筛选模式

        # g = (i for i in range(50) if i % 2 == 1)
        # for i in g:
        #     print(i)
        
    5. 字典推导式(了解)

      # print({i:i+1 for i in range(10)})
      # print({i:i+1 for i in range(10) if i % 2 == 0})
      # {键:值 for循环 加工条件}
      
    6. 集合推导式(了解)

      # print({i for i in range(10)})
      # print({i for i in range(10) if i % 2 == 0})
      
  • 相关阅读:
    java实现第四届蓝桥杯核桃的数量
    java实现第四届蓝桥杯核桃的数量
    java实现第四届蓝桥杯核桃的数量
    java实现第四届蓝桥杯核桃的数量
    java实现第四届蓝桥杯逆波兰表达式
    jsp中生成的验证码和存在session里面的验证码不一致的处理
    使用session实现一次性验证码
    java图形验证码生成工具类及web页面校验验证码
    关于在页面得到的servlet验证码总是上一次保存在session中的
    FreeMarker 获取页面request、session
  • 原文地址:https://www.cnblogs.com/zhangdadayou/p/11415210.html
Copyright © 2011-2022 走看看