[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">
:-: 
***微信掃一掃,關注“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 高級特性_列表處理