zoukankan      html  css  js  c++  java
  • python——列表生成式、生成器

    一、列表生成式

    根据表达式,一次性生成一个列表。缺点:占用内存空间;

    [x for x in range(10)]    # 生成列表 [0,1,2,3,4,5,6,7,8,9]
    
    [x*2 for x in range(10)]  # 生成列表 [0,2,4,6,8,10,12,14,16,18]
    

    二、迭代器Iterator

    生成器都是迭代器,迭代器不一定是生成器。Iterator(迭代器),Iterable(可迭代对象)。满足两个条件即为迭代器:有iter方法;有next方法;

    l=[1,2,3,4,5]
    l.__iter__()      # 根据列表l生成一个可迭代对象;等效于 iter(l),并且推荐使用iter()函数;
    

    for循环内部做的三件事:

    • 调用可迭代对象的iter方法返回一个迭代器对象;
    • 不断调用迭代器对象的next方法;
    • 处理stopIteration异常;

    三、生成器Generator

    一边循环一边计算的机制,称为生成器(Generator)。生成器本身就是一个可迭代对象。生成器其实就是一种特殊的迭代器。

    列表生成式是生成一个列表;生成器是储存一个算法,每次调用时都会计算出下一个值。

    生成器有两种生成方式:

    • 1、 将列表生成式的 [ 改为 (

      (x for x in range(10))
      
    • 2、 yield

      def foo():
          print("in the func foo.")
          return "foo"
      foo()         # 这里foo是一个函数。
      
      
      def foo():
          print("in the func foo.")
          yield "foo"
      foo()         # 这里foo是一个函数,但是是一个生成器函数。foo()就是一个生成器对象
      

    生成器调用

    在python2中,生成器有个方法next,直接 generator.next()即可调用。

    在python3中,这个方法被取消了,改为了next内置方法。不建议使用。代替的为 next函数。官方也建议这么做:使用next函数进行调用。

    1. def foo2():
          print("in the func foo.")
          yield "111"
      
          print("222 in the foo.")
          yield 2
      
          return 333    # 如果没有return,默认是 return None;当生成器调用溢出时,会抛出这个异常;
      
      f=foo2()          # 调用生成器函数foo2,生成一个生成器
      
      next(f)           # 第一次调用,打印 in the func foo.;返回 “111”
      next(f)           # 第二次调用,打印 222 in the foo. ;返回 2
      next(f)           # 报错 StopIteration ,因为生成器函数只有两个yield,所有生成器f只能取两个元素。当取第三个时,因为不存在,所有报异常。如上面有return,则返回异常: StopIteration 333
      

      注:在上面例子中,不要这样调用: next(foo2());这样调用永远返回第一个元素,因为每次执行调用next(foo2())时,都是调用生成器函数,都重新生成一个生成器;故,切记千万不要在next()中写 foo2()形式;

    生成器的函数send

    生成器的send函数是用来给yield前面的变量传递一个值。但是如果第一次调用send方法前没有next调用,则send只能传递一个None。

    1. def foo2():
          print("in the func foo.")
          pre_send=yield "111"
      
          print(pre_send)
          print("222 in the foo.")
          yield 2
      
      f=foo2()
      
      f.send(None)                 # 等价于  next(f)
      f.send('send for test')      #这里相当于把 'send for test' 传递给了第一个yield;然后yield赋值给了pre_send变量。
      

    利用生成器,生成一个斐波那契生成器:

    def fib():
        a = 0
        b = 1
        l = [0,1]
        yield a
        yield b
        for i in range(11+1)[3:]:
            a,b=b,a+b
            result = b
            l.append(result)
            yield result
    
    g=fib()
    print(next(g))
    print(next(g))
    如需转载,请注明出处,否则本人会追究法律责任!
  • 相关阅读:
    web应用模式
    Win10升级本地Django版本,以及DRF框架的安装使用
    DRF作业(1)
    中间件作业
    复习day03作业
    python基础复习
    利用自定义中间件来实现DRF框架中的request对象的data属性
    复习Day02(python中魔法方法,cookie/sesison/token,pymysql)
    排序之快排
    排序之归并
  • 原文地址:https://www.cnblogs.com/hacker001/p/10091441.html
Copyright © 2011-2022 走看看