Python的生成器(Generator)
通过列表生成式可以直接创建一个列表,但是,列表生成式受到内存限制,因为列表容量肯定是有 限的。如果创建一个包含100万个元素的列表,那么这将会占用很大的存储空间。若仅仅只访问前面几个元素,则后面绝大多数元素占用的空间都浪费了。所以,如果列表元素可以按照某种算法推算出来, 那就可以在循环的过程中不断推算出后续的元素。这样就不必创建完整的list,从而节省大量的空间。在 Python中,这种一边循环一边计算的机制,被称为生成器(Generator)。生成器是实现迭代器的一种机制。其功能的实现依赖于yield表达式,除此之外它跟普通的函数没有两样。
简单生成器
要创建一个Generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[ ]改成( ),就创建了一个Generator:
>>> L = [x * x fbr x in range(10)]
>>> g = (x * x fbr x in range(10))
>>>
>>> print(L)
[0,1,4,9,16,25,36,49,64,81]
>>> print(g)
<generator object <genexpr> at 0x03B54600>
在 Python 3 中:
>>> g = (x * x for x in range。))
>>> print(g.next())
Traceback (most recent call last):
File '<stdin>', line 1, in <module>
AttributeError: 'generator* object has no attribute 'next*
>>> print(g.__next__())
0
>>> print(g.__next__())
1
>>> print(next(g)) #这里*2*种写法都可以
4
>>> print(g.__next__())
Traceback (most recent call last):
File '<stdin>', line 1, in <module>
Stopiteration
>>>
Generator保存的是算法,每次调用next(),就可以计算出下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出Stopiteration的错误。当然,上面这种不断调用next()。方法不推荐使用,正确的方法是使用for循环,因为Generator也是可迭代对象
g=(x * x for x in range(3))
for n in g:
print(n)
带yield语句的生成器
如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个Generator。 与普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,可以简单理解为:生成器 就是一个迭代器。在调用生成器运行的过程中,每次遇到yield时函数会暂停并保存当前所有的运行信息, 返回yield的值,并在下一次执行next。方法时从当前位置继续运行。调用一个生成器函数,返回的是一 个迭代器对象。
range功能:
range(start, stop[, step])
参数说明:
- start: 计数从 start 开始。默认是从 0 开始。例如range(5)等价于range(0, 5);
- stop: 计数到 stop 结束,但不包括 stop。例如:range(0, 5) 是[0, 1, 2, 3, 4]没有5
- step:步长,默认为1。例如:range(0, 5) 等价于 range(0, 5, 1)
例如:
for i in range(3,-1,-1):
print(i)
运行结果:
3
2
1
0
生成器
def reverse(data):
for index in range(len(data)-1, -1, -1):
yield data[index]
>>>
>>> for char in reverse('golf'):
... print(char)
...
f
l
o
g