欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Python 迭代器(iterator)和生成器(generator)

程序员文章站 2024-02-12 12:40:16
...

1、迭代器(iterator)

迭代器 迭代是Python最强大的功能之一,是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象。 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。  迭代器有两个基本的方法:iter() 和 next()。

iter()创建迭代器对象

 字符串,列表或元组,集合对象都可用于创建迭代器。

>>> list=[1,2,3,4] 
>>> it = iter(list)    # 创建迭代器对象 
>>> print (next(it)) # 输出迭代器的下一个元素 1 
>>> print (next(it)) 2 

2、生成器(generator)

什么是yield呢

  yield 的作用就是把一个函数变成一个generator,带有 yield 的函数不再是一个普通函数,Python 解释器会将其视为一个生成器,如调用Xun函数,不会执行该函数,而是返回一个iterable迭代对象!    区别:与return类似,都可以返回值,但不一样的地方,yield可以返回多次值,而return只能返回一次。

def Xun(max):
    n=0
    b=1
    while n < max:
        yield b
        print(b)
        b+=1
        n = n + 1

什么是生成器

使用了 yield 的函数被称为生成器。跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回yield的值。并在下一次从当前位置继续运行。

def f():
    print('start')
    a = yield 1
    print(a)
    print('middle....')
    b = yield 2  # 2这个值只是迭代值,调用next时候返回的值
    print(b)
    print('next')
    c = yield 3
    print(c)

a = f()
print(next(a))    #1
print(next(a))    #2
print(next(a))    #3

 代码执行说明:

1、执行第一个next的时候,函数f()执行print('start'),然后执行yield 1,返回给调用者,结果是1,被打印出来。程序停留在yield 1,迭代器记住此时的执行的位置。

2、执行第二个next的时候,函数f() 执行 a = yield 1的赋值操作,此时a是None,赋值没有内容;执行print(a)打印结果为None;执行print('middle....');然后执行yield 2,返回给调用者,结果是2,被打印出来。程序停留在yield 2,迭代器记住此时的执行的位置。

3、执行第三个next的时候,函数f()执行b = yield 2的赋值操作;print(b)打印为None;print('next');然后执行yield 3,返回给调用者,结果是3,被打印出来。程序停留在yield3,迭代次数已经用完,只有三个迭代器,迭代程序终止。

如果再次调用next的话,程序报错 StopIteration。print(c)是永远不会被执行的。

 

生成器-send()

send(num)作用:把里面的值传进到当前迭代器的yield位置,作为yield的返回值。同时触发一次迭代过程

next(a) == a.send(None),next的效果等于send(None)

def f():
    print('start')
    a = yield 1
    print(a)
    print('middle....')
    b = yield 2
    print(b)
    print('next')
    c = yield 3
    print(c)

a = f()
print(next(a))
print(a.send('msg'))
print(a.send('msg1'))

继续拿上面的例子来讲解,此时的执行结果如下:

start
1
msg
middle....
2
msg1
next
3

 代码执行说明:

1、执行第一个next的时候,函数f()执行print('start'),然后执行yield 1,返回给调用者,结果是1,被打印出来。程序停留在yield 1,迭代器记住此时的执行的位置。

2、执行第二步a.send('msg')的时候,函数f() 执行 a = yield 1的赋值操作,此时yield是有返回值的,a是msg;执行print(a)打印结果为msg;执行print('middle....');然后执行yield 2,返回给调用者,结果是2,被打印出来。程序停留在yield 2,迭代器记住此时的执行的位置。

3、执行第三步a.send('msg1')的时候,函数f()执行b = yield 2的赋值操作,yield接受返回值msg1;print(b)打印为msg1;print('next');然后执行yield 3,返回给调用者,结果是3,被打印出来。程序停留在yield3,迭代次数已经用完,只有三个迭代器,迭代程序终止。

因为send都是会执行一次迭代过程,如果再次调用next或者send操作的话,程序报错 StopIteration。

 

send操作是往当前的迭代器yield位置返回参数,所以必须先调用next,如果程序第一次就用send的话,程序报错!

def f():
    print('start')
    a = yield 1
    print(a)
    print('middle....')
    b = yield 2
    print(b)
    print('next')
    c = yield 3
    print(c)

a = f()
print(a.send('msg'))

TypeError: can't send non-None value to a just-started generator