zoukankan      html  css  js  c++  java
  • ~~函数基础(七):生成器&迭代器~~

    进击のpython

    *****

    生成器


    上来说个这,就有点抽象了!

    我们先整点活儿

    宁,准备好了吗?

    直接相位猛冲!


    • 列表生成器

      需求来了,老弟!我有一个数组

      a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
      

      我想把列表里每个元素加一,怎么办呢?

      a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
      b = []
      for i in a:
          b.append(i+1)
      
      print()
      
      b
      

      还有吗?

      a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
      
      for index, i in enumerate(a):
          a[index] += 1
      print(a)
      

      还有吗?

      a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
      
      a = list(map(lambda x:x+1,a))
      print(a)
      

      还有吗?

      a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
      
      a = [i + 1 for i in a]
      print(a)
      

      最后一种的方式就是列表生成式(是不是很像三目运算??)


    • 生成器

      生成器,比如说我要是输出1~100

      怎么输出呢?

      for i in range(1,101):
          print(i)
      

      这大家都知道(不知道的滚回去看基础知识去,别在这捣乱)

      那有没有想过,range(1,100) 是什么呢?

      在py2.x系统下,我们可以看出来

      range(1,101)实际上是生成了一个从1~100的数字的列表

      那我要是有个这种句子呢?

      for i in range(1, 101):
          if i < 20:
              print(i)
      

      可以看出来我只需要20个数字,但是range给我生成了一个带有很多元素的列表

      即使里面大部分我都用不上,但是还是生成了。(while也行,别在这艮)

      那就会出现一个浪费空间的问题

      那我就要想了,能不能先生成一个我先用着,然后用完了再传下一个

      这个东西 就是 生成器

      做呢?有两种方式!


      将列表推导式的中括号变成小括号

      f = (x + 1 for x in range(10))
      
      print(f)                        # <generator object <genexpr> at 0x05681EF0>
      

      只是生成了生成规则,还没有产生数值

      那我要怎么产生数值呢?

      利用函数next()

      f = (x + 1 for x in range(10))
      
      print(next(f)) # 1
      print(next(f)) # 2
      print(next(f)) # 3
      print(next(f)) # 4
      print(next(f)) # 5 
      print(next(f)) # 6
      

      如果值取完了就会报错:

      要是想再使用这个生成器,那你就需要重新调用


      用循环来取

      这样就不会报错,会把值全都取出来

      f = (x + 1 for x in range(10))
      
      for i in f:
          print(i)
      

    • 函数生成器

      在做函数生成器之前,我们先试试输出100以内的斐波那契数列

      # 1 1 2 3 5 8 13 ... ...
      
      li = [1, 1]
      
      for i in range(2, 101):
          if li[i - 2] + li[i - 1] < 101:
              li.append(li[i - 2] + li[i - 1])
          else:
              break
      print(li)
      

      或者也可以这么写:

      # 0 1 1 2 3 5 8 13 ... ...
      
      a = 0
      b = 1
      count = 0
      while count < 20:
          tep = a
          a = b
          b = tep + b
          print(a,end=" ")
          count += 1
      

      那要是把这个东西改成函数怎么写??

      那很简单啊!

      # 0 1 1 2 3 5 8 13 ... ...
      
      def fib(n):
          a = 0
          b = 1
          count = 0
          while count < n:
              tep = a
              a = b
              b = tep + b
              print(a, end=" ")
              count += 1
      

      那函数生成器呢???更简单了

      看到print()没有?把 print()⇨ yield()

      大功告成!

      # 0 1 1 2 3 5 8 13 ... ...
      
      def fib(n):
          a = 0
          b = 1
          count = 0
          while count < n:
              tep = a
              a = b
              b = tep + b
              # print(a, end=" ")
              yield a
              count += 1
      
      
      print(fib(20))
      

      拿到了什么结果??(<generator object fib at 0x033A1EF0>)

      这是不是个生成器?(当然是!那么大个generator看不到啊)

      yield 暂停 你可以把它理解成 return 但是他后面的语句还是会执行的函数没有退出

      生成器是不是有 next() 函数啊,试试用 next() 打印这个结果

      有啥用???

      可太有用了!

      你没发现这个yield将函数进行中断操作了吗?

      什么意思呢?就是你可以执行着函数,然后停住他,执行点别的,再执行函数

      给你个例子,自己体会!

      # 0 1 1 2 3 5 8 13 ... ...
      
      def fib(n):
          a = 0
          b = 1
          count = 0
          while count < n:
              tep = a
              a = b
              b = tep + b
              # print(a, end=" ")
              yield a
              count += 1
      
      
      f = fib(20)
      print(next(f))
      print(next(f))
      print('-----"下面是上两个的和"-----')
      print(next(f))
      print(next(f))
      print(next(f))
      print(next(f))
      


    这个东西还是比较抽象的,但是很重要的熬,所以建议多练习

    自己试试输出一下斐波那契数列

    好好看看!很重要的!!!!!!!!!!!!!!


    迭代器


    回想一下啊,都有什么可以用for这个方法来循环呢?

    list tuple dict set str

    还有什么?

    嗯!上面写的生成器 genterator

    那就出来了┗|`O′|┛ 嗷~~

    我们把这些可以用for方法循环的对象称为可迭代对象 iterable

    这个词的意思就是可以遍历,可以循环的

    # 西瓜:三天之后,大家就知道什么是迭代了
    # 读者:A,他是别人的老师,现在又成了你的朋友。你给翻译翻译,什么叫迭代?翻译翻译,什么叫迭代?
    # A:这还用翻译,都说了。
    # 读者:我让你翻译给我听,什么叫迭代?
    # A:不用翻译,这就是迭代啊。
    # 西瓜:难道你听不懂什么叫迭代?
    # 读者:我就想让你翻译翻译,什么叫迭代!
    # A:迭代嘛
    # 读者:翻译出来给我听,什么他妈的叫迭代!什么他妈的叫他妈的迭代!
    # A:什么他妈的叫惊喜啊?
    # 西瓜:迭代就是可以用for方法循环的对象!明白了吗?
    # A:这就是迭代啊
    # 读者:翻译翻译 翻译翻译!
    # A:迭代就是可以用for方法循环的对象!
    # 读者:哈,大哥这他妈的就是迭代啊!小弟懂了
    # 西瓜:好
    

    可以被next()函数调用并不断返回下一个值的对象成为迭代器 :iterator

    而 生成器都可以迭代,而且还有next()方法

    所以生成器就可以约等于迭代器


    *真的重要*
    *必须康康*
  • 相关阅读:
    为表增加列属性方法探究
    细聊冗余表数据一致性
    缓存架构设计细节二三事
    缓存与数据库一致性保证
    MySQL批量SQL插入性能优化
    Codeforces 1150
    Codeforces 1155
    Codeforces 331D
    Windows & Ubuntu Vscode 配置c++环境
    后缀数组
  • 原文地址:https://www.cnblogs.com/jevious/p/11142896.html
Copyright © 2011-2022 走看看