Day 12 生成器:生成器表达式:列表表达式:yield:yield from:内置函数

01 今日内容大纲

  1. 毒鸡汤课

    坚持努力。

  2. 生成器

    • yield
    • yield return
    • yield from
  3. 生成器表达式,列表推导式

  4. 内置函数 I

02 昨日内容回顾作业讲解

  1. 可迭代对象:

    • 可以更新迭代的实实在在值。
    • 内部含有'__iter__'方法的。
    • str list tuple dict set range
    • 优点:操作方法多,操作灵活,直观,
    • 缺点:占用内存。
  2. 迭代器:

    • 可以更新迭代的一个工具(数据结构)。
    • 内部含有'__iter__'``且含有__next__方法的的。
    • 文件句柄。
    • 优点:节省内存。惰性机制。
    • 缺点:不直观,速度相对慢,操作方法单一,不走回头。
  3. 格式化输出。

  4. 函数名的应用。

  5. 默认参数可变的数据类型坑。作用域的坑。

03 今日内容

  • 生成器

    • 生成器:python社区,生成器的本质就是迭代器.唯一的区别就是生成器是我们自己用python代码构建的数据结构.迭代器都是提供的,或者是转化来的

      • 获取生成器的三种方式:
        • 生成器函数
        • 生成器表达式
        • python内部提供的一些
    • 生成器函数获得生成器:

      # 函数
      def func():
          print(111)
          print(222)
          return 3
      ret = func()
      print(ret)
      
      # 生成器函数
      def func():
          print(111)
          print(222)
          yield 3
          a = 1
          b = 2
          c = a + b
          print(c)
          yield 4
      ret = func()
      print(ret)
      print(next(ret))
      print(next(ret))
      # 一个next对应一个yield
      
      • yield return
        • return:函数中只存在一个return结束函数,并且给函数的执行者返回值
        • yield:只要函数中有yield,他就是生成器而不是函数了,生成器函数中可以存在多个yield,yield不会结束生成器函数,一个yield对应一个next
    • 吃包子练习:

      def func():
          print(111)
          return 111
          yield 222
      ret = func()
      print(ret)
      print(next(ret))
      
      
      l1 = [1,2,3,4,5,6,7,8,9,10]     #先调用列表,再转化生成器,占内存
      print(iter(l1))
      # 吃包子
      函数方式,与列表没啥区别
      def func():
          l1 = []
          for i in range(1,5001):
              l1.append(f'{i}号包子')
          return l1
      ret = func()
      print(ret)
      
      def gen_func():
          for i in range(1,5001):
              yield f'{i}号包子'
      ret = gen_func()
      print(ret)
      
      for i in range(200):
          print(next(ret))
      for i in range(300):
          print(next(ret))
      
    • yield from

      # yield from(不能讲太深)
      def func():
          l1 = [1,2,3,4,5,6,7,8]
          yield l1
      ret = func()
      print(next(ret))#返回的是整个列表
      
      def func1():
          l1 = [1,2,3,4,5,6,7,8]
          yield from l1       #将l1这个列表变成了迭代器(生成器)返回
      ret = func1()
      print(next(ret))
      print(next(ret))
      print(next(ret))
      print(next(ret))
      print(next(ret))
      print(next(ret))
      print(next(ret))
      print(next(ret))
      
      
      def func():
          lst1 = ['卫龙', '老冰棍', '北冰洋', '牛羊配']
          lst2 = ['馒头', '花卷', '豆包', '大饼']
          yield from lst1
          yield from lst2
      ret = func()
      print(next(ret))
      print(next(ret))
      print(next(ret))
      
      
      g = func()    #与迭代器性质相同,ret从第四位继续读取数据
      for i in range(8):
          try:
              print(next(ret))
          except StopIteration:
              break
      
      g = func()    #用g替换ret = fun(),从头开始
      for i in range(8):
          print(next(g))
      
    • 列表表达式,生成器表达式:

      • 用一行代码构建一个比较复杂且有规律的列表
      • 列表推导式:
        • 循环模式:[变量(加工后的变量) for 变量 in iterable ]
        • 筛选模式:[变量(加工后的变量) for 变量 in iterable if 条件]
      • 循环模式讲解
      # 用一行代码构建一个比较复杂有规律的列表
      l1 = []
      for i in range(1,11):
          l1.append(i)
      print(l1)
      
      
      
      # 列表推导式
      l1 = [i for i in range(1,11)]
      print(l1)
      
      #列表推导式分为两类:
      # 1.循环模式:[变量(加工后的变量) for 变量 in iterable]
      
      # 将10以内所有整数的平方写入列表。
      l = [i**2 for i in range(1,11)]
      print(l)
      
      # 100以内所有的偶数写入列表.
      l = [i for i in range(2,101,2)]
      print(l)
      
      # 从python1期到python100期写入列表lst
      l = [f'python{i}期'for i in range(1,101)]
      print(l)
      
      # 2.筛选模式:[变量(加工后的变量) for 变量 in iterable if 条件]
      # 30以内能被3整除的数
      l = [i for i in range(1,31) if i % 3 == 0]
      print(l)
      
      # 过滤掉长度小于3的字符串列表,并将剩下的转换成大写字母
      l1 = ['barry', 'ab', 'alex', 'wusir', 'xo']
      l1 = [i.upper() for i in l1 if len(i) >= 3 ]
      print(l1)
      
      # 含有两个'e'的所有的人名全部大写留下来
      import time
      start = time.clock()
      names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],
               ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
      l = [name.upper() for i in names for name in i if name.count('e') == 2]
      print(l)
      end = time.clock()
      print(f'程序运行时长为{end-start} 秒')
      
      # 生成器表达式:
      # 与列表推导式的写法几乎一摸一样,也有筛选模式,循环模式,多层循环构建.写法上只有一个不同:
      # []换成了()
      print([i for i in range(1,11)])
      print((i for i in range(1,11)))
      obj = (i for i in range(1,11))
      # print(next(obj))
      # print(next(obj))
      # print(next(obj))
      # print(next(obj))
      # print(next(obj))
      
      for g in obj:
          print(g)
      
      # 总结:
      # 列表表达式:
          # 缺点:
          # 1. 有毒列表推导式只能构建比较复杂并且有规律的列表.不要太着迷.
          # 2. 超过三层循环才能构建成功的,不建议使用列表推导式
          # 3. 查找错误,debug模式不行
          # 优点:
              #一行构建, 简单
              # 装逼
      # 构建一个列表:[2,3,4,5,6,7,8,9,10,'J','Q','K','A']
      # l1 = [i for i in range(2,11)]+list('JQKA')
      # print(l1)
      
      # 列表推导式与生成器表达式区别:
      # 写法上:[]()
      # iterable iterator
      
      # 字典推导式(了解)
      lst1 = ['jay', 'jj', 'meet']
      lst2 = ['周杰伦','林俊杰','元宝']
      dic = {lst1[i]:lst2[i] for i in range(len(lst1))}
      print(dic)
      
      # 集合推导式(了解)
      # print({i for i in range(1,11)})
      
    • 内置函数

      # python提供了68个内置函数。
      # 今天讲的这部分大部分了解即可
      # eval 剥去字符串的外衣,运算里面的代码,有返回值
      
      s1 = '1 + 3'
      print(s1)
      print(eval(s1))
      
      s =  '{"name": "alex"}'
      print(eval(s),type(eval(s)))
      # 网络传输的str input 输入的时候,sql注入的时候,绝对不能使用eval
      
      
      
      # # exec 与 eval几乎一样
      msg = """
      for i in range(10):
          print(i)
      """
      print(msg)
      print(exec(msg))
      
      
      # hash 哈希值
      print(hash('asldjajd'))
      
      # help 帮助,在终端显示 操作方法与函数等具体用法
      s1 = 'fjdsls'
      print(help(str))
      print(help(str.upper))
      s1 = 'sfsda'
      s1.upper()
      
      
      # callable 判断一个对象是否可被调用
      s1 = 'fdsklfa'
      # s1()        #TypeError: 'str' object is not callable
      def func():
          pass
      func()
      print(callable(s1))      # False
      print(callable(func))   # True
      

04 今日总结

  1. 生成器:***
  2. 生成器函数 yield
  3. yield与return 区别。yield from
  4. 列表推导式,生成器表达式。 ***
  5. 内置函数I:今天讲的内置函数,了解。

05 预习内容

  1. lambda表达式。
  2. 内置函数 II.
  3. 闭包。
原文地址:https://www.cnblogs.com/Redbean1231/p/13338367.html