# 迭代器
[參考][1]
## 迭代器協議
由于生成器自動實現了迭代器協議,而迭代器協議對很多人來說,也是一個較為抽象的概念。所以,為了更好的理解生成器,我們需要簡單的回顧一下迭代器協議的概念。
* 迭代器協議是指:對象需要提供`next`方法,它要么返回迭代中的下一項,要么就引起一個`StopIteration`異常,以終止迭代
* 可迭代對象就是:實現了迭代器協議的對象
* 協議是一種約定,可迭代對象實現迭代器協議,Python的內置工具(如for循環,sum,min,max函數等)使用迭代器協議訪問對象。
## 可迭代對象 Iterable
直接作用于for循環的數據類型有以下幾種:
* 一類是集合數據類型,如list、tuple、dict、set、str等;
* 一類是generator,包括生成器和帶yield的generator function。
這些可以直接作用于for循環的對象統稱為**可迭代對象**:Iterable。
可以使用`isinstance()`判斷一個對象是否是Iterable對象:
~~~
>>> from collections import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance({}, Iterable)
True
>>> isinstance('abc', Iterable)
True
>>> isinstance((x for x in range(10)), Iterable)
True
>>> isinstance(100, Iterable)
False
~~~
## 迭代器
可以被next()函數調用并不斷返回下一個值的對象稱為**迭代器**:Iterator
可以使用`isinstance()`判斷一個對象是否是Iterator對象:
~~~
>>> from collections import Iterator
>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance([], Iterator)
False
>>> isinstance({}, Iterator)
False
>>> isinstance('abc', Iterator)
False
~~~
## 使用iter()將列表轉化為迭代器
## 為什么使用迭代器
這是因為Python的Iterator對象表示的是一個數據流,Iterator對象可以被next()函數調用并不斷返回下一個數據,直到沒有數據時拋出StopIteration錯誤。可以把這個數據流看做是一個有序序列,但我們卻不能提前知道序列的長度,只能不斷通過next()函數實現按需計算下一個數據,所以Iterator的計算是惰性的,只有在需要返回下一個數據時它才會計算。
Iterator甚至可以表示一個無限大的數據流,例如全體自然數。而使用list是永遠不可能存儲全體自然數的。
---
# 生成器
[參考][2]
生成器的元素在創建時,并沒有真正的產生;創建時只是指向了生成器的內存地址
* 這是一種惰性計算
* 生成器只能遍歷一次
## Python的生成器
* 語法上和函數類似:生成器函數和常規函數幾乎是一樣的。它們都是使用def語句進行定義,差別在于,生成器使用yield語句返回一個值,而常規函數使用return語句返回一個值
* 自動實現迭代器協議:對于生成器,Python會自動實現迭代器協議,以便應用到迭代背景中(如for循環,sum函數)。由于生成器自動實現了迭代器協議,所以,我們可以調用它的`next`方法,并且,在沒有值可以返回的時候,生成器自動產生`StopIteration`異常
* 狀態掛起:生成器使用yield語句返回一個值。yield語句掛起該生成器函數的狀態,保留足夠的信息,以便之后從它離開的地方繼續執行
### 生成器表達式
~~~
>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>
~~~
### 生成器函數
~~~
def fib(max):
n,a,b = 0,0,1
while n < max:
#print(b)
yield b
a,b = b,a+b
n += 1
~~~
for循環調用generator時,發現拿不到generator的return語句的返回值。如果想要拿到返回值,必須捕獲`StopIteration`錯誤,返回值包含在StopIteration的value中:
~~~
>>> g = fib(6)
>>> while True:
... try:
... x = next(g)
... print('g:', x)
... except StopIteration as e:
... print('Generator return value:', e.value)
... break
...
g: 1
g: 1
g: 2
g: 3
g: 5
g: 8
Generator return value: done
~~~
## 特性
* 只有next方法,若元素為空時會報錯,
* 不能進行通過索引進行引用和切片
* 只能通過**for**來調用
## 執行順序
函數是順序執行,遇到return語句或者最后一行函數語句就返回。
而變成generator的函數,在每次調用next()的時候執行,遇到yield語句返回,再次執行時從上次返回的yield語句處繼續執行。
## 通過生成器實現并發運算
協程
~~~
#coding: utf8
import time
def consumer(name):
print("%s 準備吃包子" %name)
while True:
print "before " + "name:" + name
baozi = yield
baozi = baozi + "name:" + name
print "after " + "name:" + name
print "包子[%s]來了,被誰[%s]吃了" % (baozi, name)
def producer(name):
a = consumer('a')
b = consumer('b')
a.next()
b.next()
print("%s開始做包子" % name)
for i in range(1):
time.sleep(3)
print("做了一個包子")
a.send("1")
b.send("2")
producer('yang')
~~~
send用于給生成器傳遞數據

[1]:http://www.cnblogs.com/huxi/archive/2011/07/01/2095931.html
[2]:http://www.cnblogs.com/huxi/archive/2011/07/14/2106863.html
- 前言
- 環境搭建
- pypi
- 打包
- Python 2 和 Python 3 的版本之間差別
- 項目
- 第一部分
- 第1章 基礎
- Python安裝
- python代碼文件類型
- python對象
- 核心數據類型
- 核心數據類型--整型和浮點型
- 核心數據類型--字符串
- str.format
- 核心數據類型--列表
- 核心數據類型--元組
- 核心數據類型--字典
- 核心數據類型--集合
- 核心數據類型--文件對象
- 調用bash
- 標準輸入輸出
- str-repr
- 字符編碼
- 迭代器和生成器
- 第2章 語句和語法
- 賦值語句
- if語句
- while語句
- for語句
- assert
- 第3章 函數
- 函數作用域
- 工廠函數
- 內置函數
- 遞歸
- 嵌套作用域和lambda
- 參數傳遞
- 函數式編程
- property可寫與可讀
- 第5章 模塊
- 模塊導入
- 模塊命名空間
- 相對導入和絕對導入
- 模塊重載
- 在模塊中隱藏數據
- 過渡性重載
- 第6章 類
- 面向對象還是面向過程?
- 構造函數 析構函數
- call
- 運算符重載
- str()
- 待定
- 即時生成屬性
- 多態
- 線程和進程
- thread模塊
- threading模塊
- threading線程鎖
- 糖果機
- multiprocessing
- 阻塞非阻塞同步異步
- 單線程和多線程對比
- 生產者消費者模型
- 第二部分
- 獲取系統資源信息
- 獲取進程所占的物理內存
- dmidecode獲取系統信息
- 網絡編程
- 網絡基礎
- python中的套接字
- socket模塊
- 第三部分 高級功能
- 閉包入門
- 閉包的應用
- 裝飾器入門
- 裝飾器應用
- 第四部分 項目實戰
- graphite
- 模塊
- collections
- datetime
- Enum
- faker
- fabric
- fileinput
- fire
- fnmatch
- getpass
- glob
- hashlib
- heapq
- json模塊
- log
- os
- Paramiko
- parser
- platform
- pyyaml
- Queue
- random
- re
- 特殊符號和字符
- re模塊
- shelves
- subprocess
- time
- urllib_urllib2_requests
- urllib urllib2
- requests
- 標準模塊ConfigParser
- 擴展模塊Mysqldb
- 擴展模塊dns
- 擴展模塊request
- uuid
- cacheout 緩存庫
- delorean 時間
- 附錄
- 內置函數
- python實現各種排序算法
- 常見報錯
- pymongo
- pyrocksdb
- 常用
- ERROR