生成器和迭代器

迭代器

迭代器iterator
同時有__next__(),__iter__()方法的數據類型能夠被稱爲迭代器
可迭代iterable
有__iter__()方法的數據類型能夠被迭代
可迭代的數據類型(iterable):list,dic,str,set,tuple,enumerate,f(文件句柄),range()
迭代器的好處:節省內存空間,從容器類型中一個一個取值,會把全部值都取到ide

print(dir([].__iter__()))#dir查看方法
range(10)#只是建立了一個迭代器,並無建立數據

生成器

生成器:本身寫的迭代器函數

1.生成器表達式

列表推導式:返回一個列表,一下返回一個列表,佔用內存較大spa

list1 =[i*i for i in range(10)]

生成器表達式:返回一個生成器(迭代器)-->幾乎不佔用內存code

gen = (i*i for i in range(10))#此時並無執行
for i in gen:  #遍歷迭代器
    print(i)

各類推導式blog

# 1.加過濾條件的推導式
gen = (i for i in range(10) if i%2==0)
for i in gen:
    print(i)

#2.嵌套列表過濾,查找names列表中含有a字符的元素
names=[['aqa','yhaga'],['wed','uhsy']]
ret = (i for name in names for i in name if 'a' in i)
for i in ret:
    print(i)
#字典推導式,key,value對調
dic = {1:'j',2:'c'}
dic_new = {dic[i]:i for i in dic}
print(dic_new)
View Code

2.生成器函數

只要函數中含有yield關鍵字就是生成器函數,yield只能在函數內部使用,且不能與return同時出現ip

#例子1:製造兩百萬個jcc
def jcc():
    for i in range(2000000):
        yield 'jcc %d'%i
gen = jcc() #生成器(迭代器)
for i in gen:
    print(i)   #for循環遍歷迭代器。邊取值邊打印,不佔內存
#例子2:監聽文件的輸入
#不用函數
with open('d:\jcc.txt',encoding='utf-8') as f:
    line = f.readline()
    while 1:
        if line:
            print(line)
#封裝成一個函數
def fun(filename):
    with open(filename, encoding='utf-8') as f:
        while 1:
            line = f.readline()
            if line.strip():
                yield line.strip()  #返回line再作其餘的處理
line = fun('d:\jcc.txt')
for i in line:
    print(i)
View Code

send

獲取下一個yield的同時,向上一個yield傳遞一個值,使用send以前必需要先調用一次next函數內存

def generator():
    print(1)
    content = yield 'jcc'#content接收send傳過來的值
    print(content)
    print(2)
    yield 2
ret = generator()#返回一個迭代器,此時並不執行函數
res = ret.__next__()#執行函數,返回yield後面的值
ret.send('hello')
print(res)
View Code

yield from

def gen():
    a='abc'
    b = '1234'
    yield from a  #至關於下面的兩行
    # for i in a:
    #     yield a
    yield from b
    # for i in b:
    #     yield b
g = gen()
for i in g:
    print(i)
相關文章
相關標籤/搜索