一迭代器python
1.1)什麼是可迭代?面試
凡是可使用for循環取值的都是可迭代的
列表 字典 元祖 字符串 集合 range 文件句柄 enumerate 這些都是可迭代的
for i in (1,2,3,4):
print(i)
1.2)可迭代協議
可迭代協議:內部含有_iter_方法都是可迭代的
迭代器協議:內部含有_next_方法都是迭代器
迭代器的優點
節省內存
#快
# 取一個值就進行接下來計算,二不須要等到全部的值都計算出來纔開始接下來的運算-快
from collections import Iterable,Iterator print(range(1,10000)) print(isinstance(range(10000),Iterable)) print(isinstance(range(10000),Iterator))
迭代器的特性:惰性運算
2、生成器
一個包含yield關鍵字的函數就是一個生成器函數。
yield能夠爲咱們從函數中返回值,可是yield又不一樣於return,return的執行意味着程序的結束,調用生成器函數不會獲得返回的具體的值,而是獲得一個可迭代的對象。
每一次獲取這個可迭代對象的值,就能推進函數的執行,獲取新的返回值。直到函數執行結束。
生成器的例子
假如我想讓工廠給學生作校服,生產2000000件衣服,我和工廠一說,工廠應該是先答應下來,而後再去生產,我能夠一件一件的要,也能夠根據學生一批一批的找工廠拿。
而不能是一說要生產2000000件衣服,工廠就先去作生產2000000件衣服,等回來作好了,學生都畢業了。。。
def cloth(num): for i in range(num): yield ("生產第%s件衣服" %i)#記錄當前所在的位置,等待下一次next來觸發函數的狀態 # print("生產第%s件衣服" %i) # g=cloth(5) for i in g: print(i)
g=cloth(5)
for i in g:
print(i)
# print(next(g))
# print(next(g))
生成器函數的調用不會觸發代碼的執行,而是會返回一個生成器(迭代器0
想要生成器函數執行要用next
生成器的應用
#使用生成器來監聽文件 import time def listener_files(): with open('access.log',mode='r',encoding='utf-8') as f: while True: line=f.readline() if line.strip(): yield line.strip() else: time.sleep(1) g=listener_files() for line in g: print(line)
2.計算移動工資編程
def agv_monery(): sum_monery=0 day=0 argv_moeny=0 while True: monery=yield argv_moeny day += 1 sum_monery +=monery argv_moeny=sum_monery/day g=agv_monery() print(next(g)) print(g.send(300)) print(g.send(500))
3、列表推導式和生成器表達式數組
1.列表推導式app
#老男孩因爲峯哥的強勢加盟很快走上了上市之路,alex思來想去決定下幾個雞蛋來報答峯哥 egg_list=['雞蛋%s' %i for i in range(10)] #列表解析 #峯哥瞅着alex下的一筐雞蛋,捂住了鼻子,說了句:哥,你仍是給我只母雞吧,我本身回家下 laomuji=('雞蛋%s' %i for i in range(10))#生成器表達式 print(laomuji) print(next(laomuji)) #next本質就是調用__next__ print(laomuji.__next__()) print(next(laomuji))
1.1)30之內全部能被3整除的數ide
multiples = [i for i in range(30) if i % 3 is 0] print(multiples) # Output: [0, 3, 6, 9, 12, 15, 18, 21, 24, 27]
1.2)30之內全部能被3整除的數的平方函數
res=([num**2 for num in range(1,30) if num%3==0]) print(res)
1.3)找到嵌套列表中名字含有兩個‘e’的全部名字spa
names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],
['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]code
print([ name for list in names for name in list if name.count('e') >=2])
2.生成器表達式對象
2.1 找到嵌套列表中名字含有兩個‘e’的全部名字
names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],
['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'], ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']] g=( name for list in names for name in list if name.count('e') >=2) for i in g: print(i)
2.2 30之內全部能被3整除的數
g=(i for i in range(30) if i%3==0) for i in g: print(i)
2.3 30之內全部能被3整除的數的平方
g=(num **2 for num in range(30) if num%3==0) for i in g: print(i)
3總結列表推導式和生成器表達式
1.把列表解析的[]換成()獲得的就是生成器表達式
2.列表解析與生成器表達式都是一種便利的編程方式,只不過生成器表達式更節省內存
3.Python不但使用迭代器協議,讓for循環變得更加通用。大部份內置函數,也是使用迭代器協議訪問對象的。
4.其餘推導式
4.1字典推導式
1)將一個字典的key和value對調
mcase = {'a': 10, 'b': 34} mcase_frequency = {mcase[k]: k for k in mcase} print(mcase_frequency)
2)合併大小寫對應的value值,將k統一成小寫
mcase = {'a': 10, 'b': 34, 'A': 7, 'Z': 3} mcase_frequency = {k.lower(): mcase.get(k.lower(), 0) + mcase.get(k.upper(), 0) for k in mcase.keys()} print(mcase_frequency)
4.2集合推導式
4.2.1計算列表中每一個值的平方,自帶去重功能
set1={i**2 for i in [-1,1,2,3]} print(set1)
4.3練習題
4.3.1)過濾掉長度小於3的字符串列表,並將剩下的轉換成大寫字母
names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'], ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']] #集合推導式 set2={ name for list in names for name in list if len(name) >3 } print(set2) #列表推導式 list1=[ name for list in names for name in list if len(name) >3] print(list1) #生成器表達式 g=(name for list in names for name in list if len(name) >3) for i in g: print(i)
4.3.2.求(x,y)其中x是0-5之間的偶數,y是0-5之間的奇數組成的元祖列表
#列表推導式 l1=[ (x,y)for x in range(5) if x%2==0 for y in range(5) if y%2==1] print(l1) #生成器表達式 g=((x,y)for x in range(5) if x%2==0 for y in range(5) if y%2==1) for i in g: print(i) #集合推導式 set22={(x,y)for x in range(5) if x%2==0 for y in range(5) if y%2==1} print(set22)
4.3.3 求M中3,6,9組成的列表M = [[1,2,3],[4,5,6],[7,8,9]]
#求M中3,6,9組成的列表M = [[1,2,3],[4,5,6],[7,8,9]] M = [[1,2,3],[4,5,6],[7,8,9]] print([list[-1] for list in M ])
4、生成器相關面試題
def demo(): for i in range(4): yield i g=demo() g1=(i for i in g) g2=(i for i in g1) print(list(g1)) print(list(g2))
def add(n,i): return n+i def test(): for i in range(4): yield i g=test() for n in [1,10]: g=(add(n,i) for i in g) print(list(g))
import os def init(func): def wrapper(*args,**kwargs): g=func(*args,**kwargs) next(g) return g return wrapper @init def list_files(target): while 1: dir_to_search=yield for top_dir,dir,files in os.walk(dir_to_search): for file in files: target.send(os.path.join(top_dir,file)) @init def opener(target): while 1: file=yield fn=open(file) target.send((file,fn)) @init def cat(target): while 1: file,fn=yield for line in fn: target.send((file,line)) @init def grep(pattern,target): while 1: file,line=yield if pattern in line: target.send(file) @init def printer(): while 1: file=yield if file: print(file) g=list_files(opener(cat(grep('python',printer())))) g.send('/test1')