[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测试开发圈”,了解更多测试教程!***
- 前言
- chapter01_开发环境
- chapter02_字符串的使用
- chapter03_列表的使用
- chapter04_字典的使用
- chapter05_数字的使用
- chapter06_元组的使用
- chapter07_集合的使用
- chapter08_输入输出
- chapter09_控制流程
- chapter10_实例练习_登录1
- chapter11_python函数入门
- chapter12_python中的类
- chapter13_轻松玩转python中的模块管理
- chapter14_掌握学习新模块的技巧
- chapter15_通过os模块与操作系统交互
- chapter16_子进程相关模块(subprocess)
- chapter17_时间相关模块(time & datetime)
- chapter18_序列化模块(json)
- chapter19_加密模块(hashlib)
- chapter20_文件的读与写
- chapter21_阶段考核2_登录
- chapter22_小小算法挑战(排序&二分法)
- chapter23_用多线程来搞事!
- chapter24_HTTP接口请求(requests)
- chapter25_接口测试框架(pytest)
- chapter26_阶段考核3_HTTP接口测试
- chapter27_HTML解析(pyquery)
- chapter28_阶段考核4_爬虫下载网易汽车
- chapter29_python中的那些编码坑
- chapter30_MySQL数据库操作
- chapter31 高级特性_迭代器与生成器
- chapter32 高级特性_装饰器
- chapter33 高级特性_列表处理