理解python中的iterator,generator以及yield

理解python中的iterator,generator以及yield

Iterables

python中可以对其内部进行遍历的类型都是iterable。从源码解读,任何一个包含返回值为迭代器(iterator)__iter__方法的对象,和包含支持下标检索的__getitem__方法的对象都是一个iterable。

>>> my_list = [i for i in range(1000)]
>>> hasattr(my_list '__iter__')
True
>>> hasattr(my_list, '__getitem__')
True

或者我们可以利用python在typing库中定义的Iterable来进行判断:

>>> from typing import Iterable
>>> my_list = [i for i in range(1000)]
>>> isinstance(my_list, Iterable)
True

或者我们可以采用另一种简单的判断方式,只要我们可以对一个对象执行for ... in ...的操作,那么它就是一个iterable。
常见的iterable包括list,dict,str,set, tuple等。

Iterator

Iterator就是一个定义了__next__方法的对象,__next____iter__方法构成了迭代器协议,前者返回下一个元素,后者返回迭代器自身。

Generator

上面提到的iterables非常常见且常用,因为我们可以存储和获取任意数量的元素,但同时也带来一个问题,当我们拥有大量的元素时,我们不希望为了获取其中一个元素就把整个iterablr读到内存中,所以这时候我们需要用到生成器(generator)。
假设我们要存放1到10000这10000个数字,如果采用列表,那么我们需要10000个地址空间。但如果利用生成器,那么就只需要一个地址空间,因为生成器直到运行时才会生成值写进内存,此时前一个值就被抛弃。当然内存的节省必然有其代价,生成器内的元素只能进行一次遍历。
生成器的创建类似list,只不过将[]替换为():

my_generator = (i for i in range(10000))

或者我们可以利用yield关键字来将一个函数定义为generator。

Yield

yield的用法类似于return的关键字,但不同的是带有yield的函数就变成了一个generator,每次执行到yield的时候返回一个生成的对象并保存当前运行状态,直到下一次调用next()继续运行下一轮迭代。
一个简单的例子:

def num_generator(num: int):
    for i in range(num):
        print('当前的i =', i)
        yield i
        print('完成第', i, '次运行\n')

iter = num_generator(3)

for i in iter:
    print(i)
    print('完成第', i, '次yield')

# Result:
# 当前的i = 0
# 0
# 完成第 0 次yield
# 完成第 0 次运行

# 当前的i = 1
# 1
# 完成第 1 次yield
# 完成第 1 次运行

# 当前的i = 2
# 2
# 完成第 2 次yield
# 完成第 2 次运行
#

参考:
https://stackoverflow.com/questions/231767/what-does-the-yield-keyword-do?page=1&tab=votes#tab-top
https://zhuanlan.zhihu.com/p/46259258

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值