生成器
推導式的弊端
受內存限制,列表容量 有限
而且,創建一個包含100萬元素的列表,卻只是用其中某幾個,
浪費空間。
所以 如果列表元素可以按照某算法推算出來,在後續使用中不斷推算,
邊循環,邊計算 --> 生成器 generator
三個創建、三種使用
- 創建生成器
# 1 列表推導式 --> 列表生成器
# [0,3,6,9,12,15,18,21,....,27]
nl_1 = [x * 3 for x in range(20)]
print(type(nl_1)) # <class 'list'>
# 生成器:
gl_1 = (x * 3 for x in range(7))
print(type(gl_1)) # <class 'generator'>
- 使用生成器
# 使用方法一
print(gl_1.__next__())
# 使用方法二
print(next(gl_1))
# StopIteration 超出 則 拋出 異常
while True:
try:
g = next(gl_1)
except Exception as e:
print(e)
break
else:
print(g)
- 創建 yield 生成器
# yield 關鍵字
def func():
n = 0
while True:
n += 1
yield n
g = func()
print(g)
print(next(g))
- 如果生成器需要往裏送值使用send方法
def gen():
i = 0
while i < 5:
temp = yield i
print('temp ', temp)
i += 1
return None
g=gen()
g0 = g.send(None)
print(g0)
g1 = g.send('呵呵')
print(g1)
g2 = g.send('oo')
print(g2)
進程 線程 協程
- 一個線程下面 多個協程
def task_1(n):
for i in range(n):
print('Doing task 1, coding ', i)
yield None # 增加yield 利用其 暫停功能
def task_2(n):
for i in range(n):
print('我正在做第二個任務,現在是 ', i)
yield
# 任務1、2 交替運行
g1 = task_1(8)
g2 = task_2(5)
while True:
try:
next(g1)
g2.__next__()
except:
break
-
生成器 generator
- 列表生成式 產生
- g = [x for x in range(20)]
- 函數 yield
- 列表生成式 產生
-
產生元素
- next(generator)
- generator.next()
- generator.send(xx)
-
應用:協程 --> 提高效率
可迭代的對象
- 生成器
- 元組 列表 集合 字典 字符串
- 如何判斷可迭代
from collections import Iterable
bl = isinstance(list, Iterable)
b2 = isinstance('abc', Iterable)
b3 = isinstance(generator, Iterable)
迭代器 Iterator
迭代 是訪問集合元素的一種方式,迭代器可以記住遍歷的位置
迭代器 從第一個元素開始,知道元素全部訪問結束
迭代器 只能向後
可以被 next() 調用 並不斷返回下一個值
-
可迭代的 不一定就是 迭代器
- 列表 可迭代。 但不是 迭代器 需 使用 iter
lt1 = [1,2,4,5,6]
it_lt1 = iter(lt1)
print(next(it_lt1))
print(next(it_lt1))
print(next(it_lt1))