可迭代物件就是序列觀念的通用化,如果物件是實際儲存的序列,或者可以在迭代工具環境(eg:for迴圈)中一次產生乙個結果的物件,就可看成是可迭代的。可迭代物件包括實際序列和按照需求而計算的虛擬序列。
常見的迭代工具:for迴圈、列表解析、in成員關係測試以及map內建函式等。
1. 檔案迭代器
#**************************readline方法*************************************
f=open('salary.txt')
f.readline() #return:'lastname hoursworked hourlywage\n'
f.readline() #return:'bob 4 80\n'
f.readline() #return:'ann 8 160\n'
f.readline() #return:''
#**************************__next__方法*************************************
f=open('salary.txt')
f.__next__() #return:'lastname hoursworked hourlywage\n'
f.__next__() #return:'bob 4 80\n'
f.__next__() #return:'ann 8 160\n'
f.__next__() #捕捉stopiteration異常
區別:readline方法到達檔案末尾時,返回空字串。而__next__方法到達檔案末尾時,會引發內建的stopiteration異常。
#**************************__next__方法*************************************
for line in open('salary.txt'):
print(line,end='')
#**************************readline方法*************************************
for line in open('salary.txt').readlines():
print(line,end='')
"""result:
lastname hoursworked hourlywage
bob 4 80
ann 8 160
"""
注意:print使用end=''來抑制每行最後新增乙個\n,因為行字串已經有乙個啦,若沒有end='',輸出將兩行隔開。
當然,以上也可以使用while迴圈來實現,但比for迴圈執行慢。
2.手動迭代:iter和next
對於乙個可迭代物件x,呼叫next(x)等同於x.__next__()
#手動迭代
l=[1,2,3]
i=iter(l)
i is l #return :false
i.__next__() #return :1
i.__next__() #return :2
next(i) #return :3
next(i) #捕捉stopiteration異常
#自動迭代
l=[1,2,3]
for i in l:
print(i)
注意:列表以及很多其他的內建物件,不是自身的迭代器,因為它們支援多次開啟迭代器。對於這樣的物件,我們必須呼叫iter來啟動迭代。
再舉乙個例子,字典的迭代
#字典的手動迭代,返回的是鍵值
d=i=iter(d)
next(i) #return :'a'
next(i) #return :'b'
next(i) #return :'c'
#字典的自動迭代
for key in d:
print(key,d[key])
#字典檢視迭代器,當要顯示時,需使用list()函式來顯示
#字典中keys方法返回可迭代的檢視物件
for key in d.keys():
print(key)
#字典中values方法返回可迭代的檢視物件
for val in d.values():
print(val)
#字典中items方法返回可迭代的檢視物件
for k,v in d.items():
print(k,v)
3. 其他迭代環境
除了for迴圈外,列表解析、in成員關係測試、map內建函式、sorted和zip等函式都使用了迭代協議,當應用於乙個檔案時,這些迭代器都會自動按行掃瞄。
#map函式
list(map(str.upper,open('salary.txt')))
#result:['lastname hoursworked hourlywage\n', 'bob 4 80\n', 'ann 8 160']
#in函式
'bob 4 80\n' in open('salary.txt') #return:true
'ann 4 80\n' in open('salary.txt') #return:false
#sorted函式
sorted(open('salary.txt'))
#result:['ann 8 160', 'bob 4 80\n', 'lastname hoursworked hourlywage\n']
#zip函式
list(zip(open('salary.txt'),open('salary.txt')))
#result:[('lastname hoursworked hourlywage\n', 'lastname hoursworked hourlywage\n'),('bob 4 80\n', 'bob 4 80\n'),('ann 8 160', 'ann 8 160')]
#enumerate函式
list(enumerate(open('salary.txt')))
#result:[(0, 'lastname hoursworked hourlywage\n'), (1, 'bob 4 80\n'), (2, 'ann 8 160')]
#filter函式,返回可迭代物件中為true的項,true項包括非空項
list(filter(bool,['spam','','ni']))
#result:['spam','ni']
4. 重訪迭代器:生成器
4.1 介紹
生成器有兩種:生成器函式和生成器表示式,它們在需要的時候才產生結果,而非立即產生結果,延遲了結果建立,節省了記憶體空間,並允許計算時間分散到各個結果請求。
狀態掛起:和返回乙個值並退出的常規函式不同,生成器函式自動在生成值的時刻掛起並繼續函式的執行。
迭代協議整合:編寫包含yield語句的def語句,將自動支援迭代協議,並且由此可能在任何迭代環境中以隨著時間並根據需要產生結果。
4.2 生成器函式的應用
#定義生成器函式,用來產生一系列的數字的平方
def gensquares(n):
for i in range(n):
yield i**2
#使用上面建立的生成器
for i in gensquares(5):
print(i,end=' ')
上述例子,也可以通過for迴圈、map或者列表解析的技術來實現,但是,相比較下,生成器在記憶體使用和效能方面都表現的更好,且能避免臨時再做所有的工作。有了生成器,函式變數就能夠自動的儲存和恢復了。
4.3 生成器表示式:迭代器+列表解析
從語法上來講,生成器表示式就像一般的列表解析一樣,但是它們是括在圓括號中而非方括號中。
#列表解析
[x**2 for x in range(4)] #result:[0, 1, 4, 9]
#生成器表示式
(x**2 for x in range(4)) #result: at 0x0000000009bd0ca8>
#呼叫list函式顯示生成器結果
list(x**2 for x in range(4)) #result:[0, 1, 4, 9]
#for迴圈自動觸發生成器
for i in (x**2 for x in range(4)):
print(i)
#如果生成器表示式是在其他的括號之內,例如函式呼叫,此時,生成器自身的括號則可以省略
sorted(x**2 for x in range(4)) #result:[0, 1, 4, 9]
#但,如果是這樣,則還是需要額外的括號的
sorted((x**2 for x in range(4)),reverse=true) #result:[9,4,1,0]
4.4 生成器函式 vs 生成器表示式
生成器函式和生成器表示式自身都是迭代器,並只支援一次活躍迭代,且都支援自動迭代和手動迭代。有趣的是,往往同樣的迭代可以用乙個生成器函式或生成器表示式編寫。等價的生成器函式需要略微多一些的**,但作為乙個多語句的函式,如果需要的話,它將能編寫更多邏輯並使用更多的狀態資訊。
Python之迭代器
我們已經知道,可以直接作用於for迴圈的資料型別有以下幾種 一類是集合資料型別,如list tuple dict set str等 一類是generator,包括生成器和帶yield的generator function。這些可以直接作用於for迴圈的物件統稱為可迭代物件 iterable。可以使用...
python之迭代器
首先需要搞清楚兩個概念 可迭代,迭代器,兩者不能混為一談。可以直接作用於for迴圈的物件統稱為可迭代物件 iterable python裡可以用isinstance iterable 來檢測第乙個引數是不是可迭代的 這裡第乙個引數是乙個列表 注意,可迭代和 迭代器 是不一樣的!可以被next 函式呼...
Python之迭代器
檔案迭代器 方法 next 手動迭代 內建函式iter和next 其他型別迭代器 自定義迭代器 具體用途 乙個實現了 iter 方法和 next 方法的物件,就是迭代器 內建函式next會自動呼叫乙個物件的 next 方法。給定乙個可迭代物件x,呼叫next x 等同於x.next 該迭代器根據需要...