003---生成器 & 叠代器
阿新 • • 發佈:2019-01-30
的區別 port lambda 容量 map 只需要 col 裝逼 return
生成器 & 叠代器
列表生成式
現在有個需求,列表[1, 2, 3, 4, 5, 6, 7, 8, 9],將列表裏的每個值加1。
- 二逼青年版
a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
b = []
for item in a:
b.append(item + 1)
a = b
print(a)
- 普通青年版
a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
for index, ele in enumerate(a, 0):
a[index] += 1
print(a)
- 文藝版(lambda + map 搭配使用)
a = [1, 2, 3, 4, 5, 6, 7, 8, 9] a = list(map(lambda x:x+1,a)) print(a)
- 裝逼青年版
a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print([i + 1 for i in a])
- 這種寫法就是列表生成式
- 習題:利用列表生成式一行代碼實現9 * 9乘法表
print('\n'.join([''.join(['%d * %d = %-3d' % (i, j, i * j) for j in range(1, i + 1)]) for i in range(1, 10)]))
生成器
- 通過列表生成式,可以直接創建一個列表,但是畢竟內存有限,列表的容量也是有限的。創建一個包含100萬個元素的列表,但是我們僅僅需要訪問前面幾個元素,這就造成了內存大量白白浪費。
- 在python中有一種更好的解決方式,邊循環邊計算的機制。稱為(generator)
- 簡單創建生成器(只需要把列表生成器的方括號改成括號)
g = (i for i in range(5))
print(type(g),g.next())
- next()取值和for循環取值
# 使用next()取值 g = (i for i in range(5)) print(type(g)) print('開始取值') print(next(g)) print(next(g)) print(next(g)) print(next(g)) print(next(g)) # print(next(g)) # 報錯:StopIteration,因為取不到值了 # 基本上不會使用next(),正確應該使用for循環。而且還不需要擔心會報錯。拿不到函數return返回值 g = (i for i in range(10)) for i in g: print(i)
- 斐波拉契
# 斐波拉契:1 1 2 3 5 8 13 21
def fbi(num):
n, a, b = 0, 0, 1
while n < num:
yield b # # 到這停止,可以理解為凍結當前代碼。並且,把值返回給外面的next()
print(a, b)
a, b = b, a + b
n += 1
for i in fbi(2):
print(i)
- 代碼解析:
- return 和 yield 的區別
- 返回並終止函數
- 返回數據,並凍結當前的執行過程。
- next()喚醒凍結函數的執行過程,繼續執行,直到遇到下一個yield
- 函數加了yield之後
- 函數()就得到了生成器,不next()不開始執行。
- return 在生成器裏,代表生成器的終止,直接報錯
- return 和 yield 的區別
- 深入
# 生成器send,相當於喚醒。
def work(n):
count = 0
while count < n:
count += 1
sign = yield count
print('sign的值:',sign)
if not sign:
yield count + 2
new_range = work(4)
# res = next(new_range) # 開始第一次取值 拿到一個1
# print(res) # 1
# res1 = new_range.send(True) # 第二次取值 發送一個true 函數遇到true 循環
# print(res1) # 2
# res2 = new_range.send(False) # 第三次取值 n=3
# print(res2)
叠代器
- 可以作用for循環的類型:
- 集合類型:str、list、tuple、dict、set
- generator:生成器和帶yield的函數
這些類型稱為可叠代對象:iterable
```python
from collections import Iterableprint(isinstance([],Iterable))
print(isinstance(‘‘,Iterable))
print(isinstance({},Iterable))
print(isinstance(set(),Iterable))
print(isinstance((i for i in range(2)),Iterable))```
- 生成器不僅可以作用域for還可以被next()不斷取值,直到沒有數據可取
from collections import Iterator
print(isinstance((i for i in range(2)),Iterator))
總結
- 凡是可以作用於for循環的對象都是可叠代對象,Iterable
- 凡是可以作用於next()的對象都是叠代器,Iterator
- 集合數據類型雖然不是叠代器,但是可以通過iter()函數變成Iterator。
003---生成器 & 叠代器