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))
posted @ 2018-12-09 15:39  hacker&haidao  阅读(300)  评论(0编辑  收藏  举报