其他分享
首页 > 其他分享> > 三大器之------生成器

三大器之------生成器

作者:互联网

生成器

一. 生成器的定义:

生成器的本质就是迭代器,在python社区中,大多数时候都把迭代器和生成器是做同一个概念。生成器和迭代器,唯一的不同就是:迭代器都是Python给你提供的已经写好的工具或者通过数据转化得来的,(比如文件句柄,iter([1,2,3])。生成器是需要我们自己用python代码构建的工具。最大的区别也就如此了。

二、生成器的构成

  1. 生成器表达式
    1. 通过生成器函数
      1. python内置函数或模块提供

三、生成器函数

def func():
    print(11)
    return 22
ret = func()
print(ret)
将函数中的return换成yield,这样func就不是函数了,而是一个生成器函数

def func():
    print(11)
    yield 22
ret = func()
print(ret)   注意:结果 <generator object func at 0x031E5CB0>

执行这个函数的时候,就不再是函数的执行了,而是获取这个生成器对象.
生成器的本质就是迭代器,迭代器如果取值,生成器就如何取值

四、生成器的取值

def func():
    print(11)
    yield 22
qener = func()  # 这个时候函数不会执行,而是获取到生成器(就是那个内存地址!!)
ret = next(qener) # 这个时候函数才会执行
print(ret)      # 并且yield会将func生产出来的数据 222 给了 ret

并且生成器函数中可以写多个yield
 def func():
     print('11')
     yield 22
     print('33')
     yield 44
 gener = func()
 ret = next(gener)
 print(ret)
 ret2 = next(gener)  # 和迭代器一样,next超过yield的个数就会报错
 print(ret2)

五、yield和return的区别

def eat():
     for i in range(1,10001):
         yield '包子'+str(i)

 e = eat()

 for i in range(200):  # 先吃200个包子
     print(next(e))    # 运行一个next就吃一个包子,非常节省内存,而且可以保留上次的位置

六、yieldfrom与yield对比

 对比 yield 与 yield from
 def func():
     lst = ['卫龙', '老冰棍', '北冰洋', '巧克力']
     yield lst
 g = func()
 print(g)
 print(next(g))  # 只是返回一个列表

 def func1():
     lst = ['卫龙', '老冰棍', '北冰洋', '巧克力']
     yield from lst
 g = func1()
 print(g)  # 它会将这个可迭代对象(列表)的每个元素当成迭代器的每个结果进行返回
 print(next(g))
 print(next(g))
 print(next(g))
 print(next(g))
'''
yield form ['卫龙', '老冰棍', '北冰洋', '巧克力']
等同于:
    yield '卫龙'
    yield '老冰棍'
    yield '北冰洋'
    yield '巧克力'
'''

 def func():
     lst1 = ['卫龙', '老冰棍', '北冰洋', '巧克力']
     lst2 = ['馒头', '花卷', '豆包', '大饼']
     yield from lst1
     yield from lst2
 g = func()
 for i in g:
     print(i)
 因为yield from 是将列表中的每一个元素返回,所以如果写两个yield from 并不会产生交替的效果
 yield from节省代码,提升效率(代替了for循环)

总结

七、列表推导式与生成器表达式

  1. 列表推导式:用一行代码构建一个有规律的列表
    • 循环模式:[变量(加工后的变量) for 变量 in interable]
    • 筛选模式: [变量(加工的变量) for 变量 in iterable if 条件]--就是在循环模式的基础上加上一个判断条件,将满足条件的变量留到列表中
一般写法
lst = []
for i in range(10):
    lst.append(i)
print(lst)   #[0,1,2,3,4,5,6,7,8,9,]

列表推导式的循环模式
lst = [i for i in range(10)]  #循环模式
print(lst)   #[0,1,2,3,4,5,6,7,8,9,]

列表推导式的筛选模式
lst = [i for i in range(10) if i % 2==0] #筛选模式
print(lst)   #[0,2,4,6,8]
  1. 生成器表达式

    • 生成器表达式和列表推导式在语法上一模一样,只要把[]换成()就可以了

      gen = (i**2 for i in range(10))
      print(gen)  #生成器内存地址
    • 如何触发生成器或迭代器

      • next
      • for循环
      • 转换,比如用list()转换成列表
    • 生成器的惰性机制

      生成器只有在访问时才取值,说白了,你找他要才给你值,不找他要,他是不会执行的

  2. 生成器表达式和列表推导式的区别

    • 列表推导式比较消耗内存,所有数据一次加载到内存,而生成器表达式遵从迭代器协议,逐个产生元素
    • 得到的值不一样,列表推导式得到的是一个列表,生成器表达式获取的是一个生成器
    • 列表推导式一目了然,生成器表达式只是一个内存地址
  3. 字典推导式

    lst1 = ['jay', 'jj', 'meet']
    lst2 = ['周杰伦', '林俊杰', 'haven']
    dic = [lst1[i]:lst2[i] for i in range(len(lst1))]
    print(dic)
    # {'jay': '周杰伦', 'jj': '林俊杰', 'meet': 'haven'}
  4. 集合推导式

    lst = [1, 2, 3, -1, -3, -7, 9]
    s={i for i in lst}
    print(s)  #{1, 2, 3, 9, -7, -3, -1}

八、匿名函数与内置函数

  1. 匿名函数:没有名字的函数,lambda

    • 只能构建简单的函数,一句话函数
    def func(x,y):
     return x+y
    print(func(x,y))
    
    func2 = lambda x,y:x+y  #lambda  定义一个匿名函数
    print(func2(1,2))
    
    func4 = lambda a,b:a if a>b else b
    #匿名函数最常用的就是与内置函数的结合使用
    
  2. 内置函数:python中的内置函数有68种

    1. eval():剥去字符串的外衣,返回最终结果,慎用

      s = '5+9'
      print(eval(s))  #14
      
    2. exec():执行字符串中的代码流,没有返回值

      s = """
      for i in [1,2,3]:
        print(i)
      """
      exec()
      
    3. hash()获取一个对象(可哈希对象:int,str,bool,tuple,)的哈希值

    4. help():查看函数或模块的详细说明

    5. callable():用于查看一个对象是否可以被调用的,如果返回True,仍有可能调用失败,但是返回False,则一定不会成功

      name = 'haven'
      def func():
        pass
      print(callable(name))  #False
      print(callable(func))  #True
      
    6. int():用于将一个字符串或数字转换为整型

      print(int())  # 0
      print(int('12'))  # 12
      print(int(3.6))  # 3
      
    7. float():用于将整数和字符串转换成浮点数

    8. complex():用于创建复数,或者将字符串或数换成复数

    9. bin():将十进制换成二进制
    10. oct():将十进制转换成八进制字符串返回

    11. hex():将十进制转换成十六进制字符串并返回
    12. divmod():j计算除数与被除数的结果,返回一个包含商和余数的元组(a//b,a%b)

      print(divmod(10,3))   #(3,1)  分页用到
      
    13. round():保留浮点数的小数位数,默认保留整数

      print(round(3.1415926,2))  #3.14 四舍五入 
      
    14. pow():求x**y次幂

      # 第三个参数为x**y的结果对z取余
      print(pow(2, 3))  # 2**3 8
      print(pow(2, 3, 3)) # 8对3取余 2
      
    15. ord():输入字符找该字符编码的位置,unicode

    16. chr():输入位置数字找出其对应的字符,unicode,有用

    17. repr():返回一个对象的string形式(原形毕露)

      print(repr('123')) # '123
      
    18. all():可迭代对象中全是True才是True

    19. any():可迭代对象中,有一个True就是True

    20. 接下来的都很重要!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    21. print():屏幕输出

      print(1,2,3,sep = '_') #1_2_3 sep设定分隔符,默认空格
      print(1,2,end=' ') # end默认是\n
      
    22. list():定义或转换列表

      lst = list('asdf')  #括号内可放迭代对象
      # ['a','s','d','f']
      
    23. dic():字典

      字典的创建方式

      dic = {1:'2'}
      dic = {i:1 for i in range(3)}
      dic = dict(one=1,two=2,three=3)
      dic = dict.fromkeys(key,valus)
      
    24. abs():获取绝对值

      print(abs(-10))   #10
      
    25. sum():求和

      sum(iterable,初始默认值为0)
      print(sum([1, 2, 3, 4])) # 10
      print(sum([1, 2, 3, 4], 10)) # 20
      
    26. max():求最大值 用法与min()完全相同

    27. min():求最小值

      print(min([22,3,43,45,3]))  # 2
       lst = [('maqian', 20), ('xihong', 18), ('xiaomi', 22)]
       找年龄最小的元组
      print(min(lst))  #('maqian', 20),按照可迭代对象的第一个元素的第一个字符排序
      
      通过设置key去使用min,key=函数名,返回值是什么就按照什么比较
      min()会自动将可迭代对象的每一个元素作为实参传给函数,最后将遍历的那个元素返回
      
      print(min(lst,key=lambda x:lst[1]))  #使用匿名函数
      
      
    28. reversed():将一个可迭代对象反转,返回反转的迭代器

      s = 'maqian'
      for i in reversed(s):
       print(i)  # n a i q a m
      
    29. bytes():编码

      s = 'haven'
      print(s.encode('utf-8'))  #第一种方法
      print(bytes(s,encoding='utf-8'))  #第二种方法
      
      编码
      b = b'\xe5\xb0\x8f\xe6\x98\x8e'
      print(b.decode('utf-8'))  # 第一种方法
      print(str(b, encoding='utf-8')) # 第二种方法
      

标签:函数,迭代,生成器,yield,lst,print,大器
来源: https://www.cnblogs.com/douzi-m/p/11234957.html