🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] ## 迭代器(iterators) **迭代器是**一个让程序员`可以遍历一个容器`(特别是列表)的 **`对象`**。 任意对象,只要定义了next(Python2) 或者__next__方法,它就是一个迭代器。 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。 ### 迭代(Iteration) 当我们使用一个循环来遍历某个东西时,这个过程本身就叫迭代。 ### 可被迭代的对象与迭代器 迭代器是可以迭代的,但是可被迭代的,不一定就是迭代器了。 例如字符串,列表或元组对象,它们都是可被迭代的,但是它们并不是迭代器。 在解释这个问题,我们需要了解一个python内置函数 `next()`,它允许我们获取一个迭代器的下一个元素 ```cmd >>> alist=[1,2,3,4] >>> type(alist) <class 'list'> >>> >>> next(alist) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'list' object is not an iterator ``` python内置函数`iter()` 可用于将一个对象转换为迭代器。 ```cmd >>> alist_it=iter(alist) >>> type(alist_it) <class 'list_iterator'> >>> next(alist_it) 1 >>> next(alist_it) 2 >>> next(alist_it) 3 >>> next(alist_it) 4 >>> next(alist_it) Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration >>> ``` 迭代器对象可以使用常规for语句进行遍历: ```python >>> alist=[1,2,3,4] >>> alist_it = iter(alist) >>> for item in alist_it: ... print(item) ... 1 2 3 4 >>> ``` ## 生成器 Generators 在python中,使用了 yield 的函数被称为生成器(generator)。跟普通函数不同的是,`生成器是一个返回迭代器的函数`,只能用于迭代操作,更简单点理解生成器就是一个迭代器。**调用生成器,会返回一个迭代器** ### yield 返回信息 在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。 下面是一个计算斐波那契数列的生成器: ```python def fibon(n): a = b = 1 for i in range(n): yield a a, b = b, a + b fibon_it=fibon(10) for x in fibon_it: print(x,end=' ') ``` 运行结果: ```cmd 1 1 2 3 5 8 13 21 34 55 ``` 代码解释: `fibon_it=fibon(10)` 将会生成一个迭代器对象fibon_it `for x in fibon_it` 通过for循环,来迭代一个迭代器对象fibon_it * 首次迭代时,代码运行到`yield a`,返回a的值,即1,打印“**1**”然后暂停。 * 第二次迭代时,代码直接从`yield`语句后面一行开始执行,运行`a,b = b,a+b` 后,a=1,b=2。在这个代码中,会因为循环又执行到`yield a`,返回a的值,此时a依然为1,打印“**1**”,然后暂停。 * 第三次迭代时,代码又从`yield`语句后面一行开始执行,运行`a,b = b,a+b` 后,a=2,b=3,返回a的值,即打印“**2**”,然后暂停 * 以此类推 ### yield 接收信息 当生成器的`next()`方法被调用时,它会准确地从离开地方继续执行。当生成器的`send()`方法被调用时,yield会接收send方法传入的实参,并且从yield暂停的地方开始继续执行。 ```python def simple_gen(): print("waiting for name.") while True: name = yield print(name) gen = simple_gen() # 创建生成器对象 next(gen) # 执行next()方法时,程序运行到name=yield就退出,等待send传入参数。 print("-----") gen.send("Milton") # 一旦调用send()方法,回到yield退出位置,yield接收send实参,并且继续往下运行 print("-----") gen.send("Cherish") print("-----") ``` 运行结果如: ```cmd waiting for name. ----- Milton ----- Cherish ----- ``` <hr style="margin-top:100px"> :-: ![](https://box.kancloud.cn/2ff0bc02ec938fef8b6dd7b7f16ee11d_258x258.jpg) ***微信扫一扫,关注“python测试开发圈”,了解更多测试教程!***