迭代器是一个让程序员可以遍历一个容器(特别是列表)的对象。然而,一个迭代器在遍历并读取一个容器的数据元素时,并不会执行一个迭代。因为这个有三个部分:
可迭代对象(Iterable)
迭代器(Iterator)
迭代(Iteration)
可迭代对象(Iterable)
python中任意对象,只要它定义了可以返回一个迭代器的iter方法,或者定义了可以支持下标索引的getitem方法那么它就是一个可迭代对象。可迭代对象就是能提供迭代器的任意对象。
迭代器(Iterator)
任意对象,只要定义了next(python3)方法,他就是一个迭代器。
迭代(Iteration)
迭代就是从某个地方,取出元素的过程。
我们使用一个循环来遍历某个东西是,这个过程本身就叫迭代。
生成器(Generators)
生成器函数:只要函数里有了yield关键字就是一个生成器
生成器也是一种迭代器,但是你只能对其迭代一次。因为它们并没有把所有的值存在内存中,而是在运行时生成值。你通过遍历来使用它们,要么用一个“for”循环,要么将它们传递给任意可以进行迭代的函数和结构。
大多数时候生成器是以函数来实现的,然而,它们并不返回一个值,而是yield(生成)一个值。
def generator_func():
for i in range(10):
yield i
for item in generator_func();
print(item)
#output
#0
#1
...
#9
生成器最佳应用场景是:你不想同一时间将所有计算出来的大量结果分配到内存中,特别是结果集中还包含循环。这样做会消耗大量的资源
在许多python2里的标准库里都会返回一个列表,而python3里都改为返回生成器,因为生成器占用的资源更少。
# generator version
def fibon(n):
a = b = 1
for i in range(n):
yield a
a, b = b, a + b
#Now we can use it like this:
for x in fibon(1000000):
print(x)
在这里yield掉所有的值后,next()触发了一个StopIteration的异常。基于这个异常我们可以知道所有的值都被yield完了,但是在 for循环时却没有这个异常,原因是,for循环会自动捕捉这个异常并停止调用next()
字符串srt对象不是一个迭代器,但是它是一个了迭代对象。这就说明他支持迭代,但我们不能直接对其进行迭代操作。如要对其使用迭代,我们可以使用iter()内置函数,他可以将一个可迭代对象返回一个迭代器对象。
my_string = "Yasoob"
next(my_string)
# Output: Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: str object is not an iterator
my_string = "Yasoob"
my_iter = iter(my_string)
next(my_iter)
# Output: 'Y'
网友评论