6.迭代器与生成器

一.可迭代对象

在介绍迭代器与生成器之前,我们首先来介绍一下可迭代对象。可迭代对象,顾名思义,就是可以“迭代”的对象。所谓迭代,就是一个 通过for循环遍历出对象中所有元素 的过程。那么可迭代对象,便是可以实现这个过程的对象了。

在Python中,很多对象都是可迭代的,比如列表(list)、字典(dict)、元组(tuple)、集合(set)、字符串(str)、字节(bytes)等等,并且这些可迭代对象,都实现了__iter__()魔法方法。

二.迭代器(iterator)

1.迭代器的定义

迭代器属于可迭代对象,但又与可迭代对象有一点不同,它的定义是:一种可以作用于next函数的可迭代对象。迭代器不仅实现了__iter__()方法,而且实现了__next__()方法,这是区别迭代器与可迭代对象的一个重要特征!

2.迭代器的创建

(1)我们可以通过 iter(iterable) 函数将可迭代对象转换成迭代器,得到一个迭代器对象。

3.迭代器的特点
(1)我们可以通过 iter(iterable) 函数将可迭代对象转换成迭代器,得到一个迭代器对象。

(1)迭代器只可往后遍历,不可回溯。

(2)我们可以使用next()函数一次取出迭代器中的元素,直至取完其中的所有元素。如果取完后继续使用next方法,程序会抛出 StopIteration 异常:

it = iter([0,1,2])   #通过iter()函数的到一个迭代器对象

print(it)    #查看迭代器对象

#调用next()函数一次获取迭代器中元素
print(next(it))
print(next(it))
print(next(it))
print(next(it))

打印结果:
在这里插入图片描述

我们同样可以通过for循环遍历获得迭代器中的元素。

三.生成器(generator)

1.生成器的定义

我们经常使用列表,字典等可迭代对象来存放数据,但由于内存优先,如果我们要存放的数据非常多,全部放在这些容器中,那么存储空间肯定是不够的,很容易导致内存溢出。为了解决这个问题,就有了生成器这样一个概念:通过存储某种特定的算法,在需要时,一边计算一边调用的机制,成为生成器。

2.生成器的创建

(1)将列表推导式的方括号[]改为()即可的到一个生成器

g = (i for i in range(5))
print(type(g))    #<class 'generator'>

(2)一个函数中若包含了yield关键字,则这个函数就变成了一个生成器

#利用生成器实现的斐波那契数列
def fibonacci(n):
    a, b, num = 0, 1, 0

    while n > num:
        yield a    #将a的值返回出去再继续执行后续代码
        
        a, b = b, a+b
        num += 1

f = fibonacci(5)
print(type(f))   #<class 'generator'>

3.生成器的特点

(1)生成器同样可以通过next()函数进行调用

g = (i for i in range(5))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))

打印结果:
在这里插入图片描述

生成器也可以通过for循环进行遍历

(2)yield关键字

yield关键字和函数中的return很像,都是将函数执行的结果返回出去,但yield关键字在执行后不会像return一样立即退出函数体,而是暂停,等待下一次启用生成器继续在该函数体内作用。return 与 yield 的关系可以类比循环中的break 和 continue 的关系。

(3)生成器的send()方法
send()方法和next()方法一样,可以启动生成器,不同的时send可以向生成器中传入值,如图:
在这里插入图片描述
我们第一次next(f)后,程序执行到yield i 返回i的值给f,并且暂停。

第二次next(f)程序从上一次暂停的位置继续向后执行,由于yield i 将i的值返回给了f,即此时的 等号右边的值为空值None 因此None被赋值给了a,接下来执行print(a)打印出来的值就变成了None;接着程序继续执行,进入第二次循环,此时i值为1,再次碰到yield i ,又一次将i返回给f,因此此时输出了1,程序暂停。

第三次,我们使用send()方法,向生成器中传入数据‘666’。send方法和next一样,再次启动生成器,程序从第二次暂停的地方 yield i 后开始执行,由于我们使用了send方法,该方法会在此时将由于返回出去i而变为空值None的等号右边重新赋值为传入的数据’666’,即此时 a = ‘666’,接下来执行print(a)将打印出666;接下来程序继续执行,再一次进入循环,此时i的值变为2,再次执行到yield i 将i返回给f ,输出2。

通过这个例子,我们就可以对生成器的 yield 关键字和send()方法有了基本的一些了解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值