Python迭代器 iterator(iter & next) & 生成器 generator(yield) & yield

迭代器

1、通过iter()方法获得了list的迭代器对象,然后就可以通过next()方法来访问list中的元素了。

   当容器中没有可访问的元素后,next()方法将会抛出一个StopIteration异常终止迭代器。

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

2、迭代器的限制

    不能回到开始

   也无法复制一个迭代器。

   因此要再次进行迭代只能重新生成一个新的迭代器对象。

3、__iter__() 和 __next__() 方法

__iter__() 和 __next__() 方法这两个方法是迭代器最基本的方法:

一个用来获得迭代器对象

一个用来获取容器中的下一个元素

_list = [5,6,7]
it = iter(_list)
print(_list)
print(it)
print(it.__next__())
print(it.__next__())
print(it.__next__())
print(it.__next__()) #此时调用会抛出异常

另一种调用方法

_list = [5,6,7]
it = iter(_list)
print(_list)
print(it)
print(next(it))
print(next(it))
print(next(it))
print(next(it)) #此时调用会抛出异常

遍历迭代器

list_ = [5,6,7]
it = iter(list_)
print(it)
for i,v in enumerate(it):
    print(i,v)

生成器

    在一个函数中,只要有yield。那么这个函数就不再是函数,而成了一个生成器

    生成器的本质就是迭代器,生成器是一种特殊的迭代器

    如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的ist,从而节省大量的内存资源

    在Python中,这种一边循环一边计算的机制,称为生成器(Generator)

    生成器的作用:可以实现多任务(协程-->模拟并发)

    生成器包括两种:生成器函数和生成器表达式

遍历生成器

list(a)

for i in a:
    print(i)

for idx,param in enumerate(net.parameters()):
    print(param)

生成器表达式

将列表解析式[] 改成 () 即可。

g = (x*x for x in range(10))
print(g)
print(next(g))
print(next(g))
print(next(g))
print(next(g))

但是生成器不能通过类来实现

生成器函数

      生成器函数返回数据就不适用return这个关键字了,是用yield

      一个包含yield关键字的函数就是一个生成器函数。(python中yield关键字是区分新老Pythoner的标志之一)

      并且yield不能和return共用,并且yield只能用在函数内

      yield关键字,其作用和return的功能差不多,就是返回一个值给调用者,只不过有yield的函数返回值后函数依然保持调用yield时的状态,当下次调用的时候,在原先的基础上继续执行代码,直到遇到下一个yield或者满足结束条件结束函数为止

(1)生成器函数执行之后会得到一个生成器作为返回值,并不会执行函数体。

(2)执行了__next__()方法之后才会执行函数体,并且获得返回值。

(3)生成器内部支持了生成器协议,不需要明确定义__iter__() 和 __next__()方法

(3)yield和return相同的是可以返回值,但是不同的是yield 不会结束函数

def test():
    yield 1
    yield 2
    yield 3
t = test()

print(next(t))#output:1
print(next(t))#output:1
print(next(t))#output:1
print(next(t))#output:Traceback (most recent call last):StopIteration

       好像并没啥卵用啊!骚年,存在即合理,python有生成器不是没有道理的。数学中有很多算法是无限穷举的(比如自然数),我们不可能一一穷举出来,所以生成器就可以帮助我们。

def foo(num):
    print("starting...")
    while num<10:
        num=num+1
        yield num
for n in foo(0):
    print(n)

理解yield的作用

def fibonacci(n):
    a = 0
    b = 1
    nums = []
    for _ in range(n):
        nums.append(a)
        a,b = b, a+b
    return nums
for i in fibonacci(10):
    print(i)

可以写为

def fibonacci(n):
    a = 0
    b = 1
    for _ in range(n):
        yield a
        a,b = b, a+b
for i in fibonacci(10):
    print(i)

这里的yield表示,每当我们计算出一个元素,就立马将这个元素给送出去。也就是说,外面的for循环就会立即输出这个数。

因此使用yield的好处是,我们并不需要等待整个列表都生成完毕后,再来一个一个的输出。同时也可以节省存储空间。

yield的优势在于一些非常耗时的操作,比如我们可以写一个函数从网络上下载一系列文档,并输出每个文档的内容。如果我们使用yield,则可以保证在一个文档被下载成功后,就立马输出它的内容,而无需等待所有文档都下载完毕。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值