一、前言
本小节简单介绍了生成器和迭代器的工作机制和常见形式。
环境说明:Python 3.6、windows11 64位
二、生成器generator
生成器的工作机制就是边循环边计算,可以根据需要获取数据,在Python中,这种一边循环一边计算的机制,都可称为生成器。
生成器的一大优点就是即需即取,不需要占用太多的内存,避免资源浪费。
创建生成器常用两种方法:
- 借用列表生成式
- 采用函数+yield
2.1 借用列表生成式
该方法很简单,只要把一个列表生成式的[]
改成()
即可。
>>> ls = [x for x in range(3)]
>>> ls
[0, 1, 2]
>>> g = (x for x in range(3))
>>> g
<generator object <genexpr> at 0x0000020A1F3B1A50>
创建好生成器之后,我们可以通过next()
函数获取生成器的下一个返回值,每执行一次返回一个,直到取完生成器数据。
注意:取完数据之后,便会报错StopIteration
。
>>> next(g)
0
>>> next(g)
1
>>> next(g)
2
>>> next(g)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
当然,一般获取生成器的返回值使用for
循环进行遍历,而不会调用next()
一个个获取。
2.2 采用函数+yield
如果推算的算法比较复杂,用类似列表生成式的for循环无法实现的时候,还可以用函数来实现。
yield作用:阻断并返回。
使用yield
的生成器函数和普通函数的执行流程不一样。普通函数按顺序执行,一次性执行完,遇到return语句或者最后一行函数语句就返回。而生成器函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。
接下来使用yield
创建一个简单的函数了解其工作流程。
def gene():
print('return 1 and stop.')
yield 1
print('return 2 and stop.')
yield(2)
return 3
>>> g = gene()
>>> g
<generator object gene at 0x0000020A1F3B1E40>
>>> next(g)
return 1 and stop.
1
>>> next(g)
return 2 and stop.
2
>>> next(g)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
发现都没有函数return
的返回值,该怎么获取呢?该值在最后的报错中,可以通过StopIteration.value
获取。
def gene():
print('return 1 and stop.')
yield 1
print('return 2 and stop.')
yield(2)
return 3
g = gene()
while True:
try:
x = next(g)
print(x)
except StopIteration as e:
print('return:',e.value)
break
三、迭代器Iterator
可以被next()
函数调用并不断返回下一个值的对象称为迭代器(Iterator)。它是可迭代对象(Iterable),我们可以遍历其所有值。
我们可以通过isinstance()
函数来判断一个对象是不是迭代器或者可迭代对象。
迭代器包含了生成器可作用于next()
函数的对象,不包含list
、tuple
、dict
、set
、str
等;
可迭代对象包含迭代器、list
、tuple
、dict
、set
、str
等可作用于for循环的对象。
>>> from collections.abc import Iterable,Iterator
>>> isinstance([], Iterable)
True
>>> isinstance([], Iterator)
False
>>> isinstance({}, Iterable)
True
>>> isinstance({}, Iterator)
False
>>> isinstance('abc', Iterable)
True
>>> isinstance('abc', Iterator)
False
>>> isinstance((x for x in range(3)), Iterable)
True
>>> isinstance((x for x in range(3)), Iterator)
True
把list
、tuple
、dict
、set
、str
等变成迭代器可以使用iter()
函数:
>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter({}), Iterator)
True
>>> isinstance(iter('abc'), Iterator)
True
可以通过map()
生成一个迭代器。
>>> func = lambda x : x * x
>>> iter = map(func, [1, 2, 3, 4])
>>> isinstance(iter, Iterable)
True
>>> isinstance(iter, Iterator)
True
>>> next(iter)
1
>>> next(iter)
4
>>> next(iter)
9
四、小结
1、生成器创建方法之一:把一个列表生成式的[]改成();方法之二是在函数中加入yield
关键字;
2、迭代器可以被next()函数调用并不断返回下一个值,包含生成器等;list、tuple、dict、set、str等可迭代对象虽然不是迭代器,但可以使用iter()
函数作用于它们,使得变成迭代器。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/66929.html