### 1.1.1. 生成器
列表生成器產生的列表很占用內存空間,我們每次在計算使用的時候都是對單個元素進行操作,這樣其它元素占用的空間就白白浪費了。所以如果列表內的元素可以按照某種算法推算出來,這樣我們就可以在循環過程中不斷的推算下一個元素,從而避免創建完整的列表而占用大量內存。 在Python中我們把一邊循環一邊計算的的機制稱為**生成器:generator.**
生成器類似于返回值為數組的一個函數,這個函數可以接受參數,可以被調用,但是,不同于一般的函數會一次性返回包括了所有數值的數組,生成器一次只能產生一個值,這樣消耗的內存數量將大大減小,而且允許調用函數可以很快的處理前幾個返回值,因此生成器看起來像是一個函數,但是表現得卻像是迭代器


### 1.1.2. 迭代器
**迭代器 Iterator**
1. 迭代器包含有next方法的實現,在正確的范圍內返回期待的數據以及超出范圍后能夠拋出StopIteration的錯誤停止迭代。
2. 我們已經知道,可以直接作用于for循環的數據類型有以下幾種:
* 一類是集合數據類型,如list,tuple,dict,set,str等
* 一類是generator,包括生成器和帶yield的generator function
這些可以直接作用于for 循環的對象統稱為**可迭代對象:Iterable**
可以使用isinstance()判斷一個對象是否為可Iterable對象
```
# 把list、dict、str等Iterable變成Iterator可以使用iter()函數:
a = [1,2,3,4]
iter_a = iter(a)
```
```
s='hello' #字符串是可迭代對象,但不是迭代器
l=[1,2,3,4] #列表是可迭代對象,但不是迭代器
t=(1,2,3) #元組是可迭代對象,但不是迭代器
d={'a':1} #字典是可迭代對象,但不是迭代器
set={1,2,3} #集合是可迭代對象,但不是迭代器
```
**為什么list、dict、str等數據類型不是Iterator?**
這是因為Python的Iterator對象表示的是一個數據流,Iterator對象可以被next()函數調用并不斷返回下一個數據,直到沒有數據時拋出StopIteration錯誤。可以把這個數據流看做是一個有序序列,但我們卻不能提前知道序列的長度,只能不斷通過next()函數實現按需計算下一個數據,所以Iterator的計算是惰性的,只有在需要返回下一個數據時它才會計算。
一個實現了iter方法和next方法的對象就是迭代器
Iterator甚至可以表示一個無限大的數據流,例如全體自然數。而使用list是永遠不可能存儲全體自然數的
