目錄:http://www.reibang.com/p/863c446364a8
一声邦、迭代
1邀泉、迭代:
在Python中买窟,如果給定一個(gè)list或tuple,我們可以通過(guò)for循環(huán)來(lái)遍歷這個(gè)list或tuple贾铝,這種遍歷我們成為迭代(Iteration)隙轻。
2、可迭代對(duì)象:
(1)垢揩、定義
字面意思:可以進(jìn)行循環(huán)更新的一個(gè)實(shí)實(shí)在在的值玖绿。
專(zhuān)業(yè)角度:內(nèi)部含有'__iter__'方法的對(duì)象。
我們之前學(xué)過(guò)的可迭代對(duì)象有:列表叁巨、字符串斑匪、元組、字典锋勺,集合蚀瘸、range、文件庶橱。
(2)贮勃、獲取對(duì)象的所有方法并且以字符串的形式表現(xiàn):dir()
st1="python"
li1=[1,2,3]
print(dir(st1))? ? ? ? ? ? ? #這是將會(huì)運(yùn)行出st1所有的方法
print(dir(li))
(3)、判斷一個(gè)對(duì)象是否是可迭代對(duì)象
st1="python"
print('__iter__' in dir(st1))? ? #判斷st1是否為可迭代對(duì)象
print('__iter__' in dir(range(10)))? ? ? #判斷range(10)是否為可迭代對(duì)象
運(yùn)行結(jié)果為:
True
True? ? #當(dāng)對(duì)象為可迭代對(duì)象是返回True
或者
from?collections import Iterable? #判斷之前需導(dǎo)入內(nèi)置庫(kù)
s='hello'
print(isinstance(s,Iterable))?????? #判斷是不是可迭代對(duì)象
運(yùn)行結(jié)果為:
True
(4)苏章、可迭代對(duì)象的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
1寂嘉、存儲(chǔ)的數(shù)據(jù)直接能顯示,比較直觀枫绅。
2泉孩、擁有的方法比較多,操作方便并淋。
缺點(diǎn):
1寓搬、占用內(nèi)存
2、不能直接通過(guò)for循環(huán)县耽,不能直接取值(索引订咸,key)
二、迭代器
1酬诀、定義:
內(nèi)部含有'__iter__'方法并且含有'__next__'方法的對(duì)象就是迭代器。
2骆撇、判斷是否為迭代器:
'__iter__'and '__next__'在不在dir(對(duì)象)(我們之前學(xué)過(guò)的迭代器只有文件)
f=open("1.txt","r")
print('__iter__'in dir(f)and '__next__'in dir(f))
運(yùn)行結(jié)果為:
True
3瞒御、可迭代對(duì)象可以轉(zhuǎn)換為迭代器
st1="python"
obj=iter(st1)? ? ?#將st1轉(zhuǎn)換為迭代器
print(obj)? ? ? ? ? ?#輸出的結(jié)果是字符串迭代器對(duì)象的地址
運(yùn)行結(jié)果為:?
<str_iterator object at 0x03716CB0>
##當(dāng)st1為迭代器時(shí)就可以用'__next__'方法了
print(next(obj))? #注意這時(shí)是把obj作為一個(gè)迭代器,并不是st1,st1還是可迭代對(duì)象神郊。
運(yùn)行結(jié)果為:
p? ? #運(yùn)行一次next方法就輸出一次字符肴裙,直到字符串中所有字符全部輸出時(shí)趾唱,再
次運(yùn)行就會(huì)報(bào)錯(cuò)。
print(next(obj))?
print(next(obj))?
print(next(obj))?
print(next(obj))?
print(next(obj))? ??? #這時(shí)字符全部輸出
print(next(obj))? #這時(shí)在print時(shí)就會(huì)報(bào)錯(cuò)
報(bào)錯(cuò)為:
print(next(obj))
StopIteration
4蜻懦、遍歷可迭代對(duì)象和遍歷迭代器的區(qū)別:
#可迭代對(duì)象
li=[1,2,3,4,5,6,7,,8,9,10]
count=0
for i in li:
????if count ==4:
? ? ? ? break
? ? else:
? ? ? ? print(i)
? ? count +=1
count=0
for i in li:
????if count ==6:
break
else:
print(i)
? ? count +=1
運(yùn)行結(jié)果為:
1 2 3 4 1 2 3 4 5 6
#迭代器
li=[1,2,3,4,5,6,7,,8,9,10]
obj=iter(li)
for i in range(4):
? ? print(next(obj))
for i in range(6):
????print(next(obj))
運(yùn)行結(jié)果為:
1
2
3
4
5
6
7
8
9
10
當(dāng)我們遍歷可迭代對(duì)象時(shí)甜癞,每一次循環(huán)都會(huì)開(kāi)頭遍歷。而當(dāng)我們遍歷迭代器時(shí)宛乃,會(huì)接著上次執(zhí)行到的位置再次執(zhí)行悠咱。
5、迭代器的優(yōu)缺點(diǎn):
優(yōu)點(diǎn):
1征炼、節(jié)省內(nèi)存
2.析既、惰性機(jī)制,next一次谆奥,去一個(gè)值眼坏。
缺點(diǎn):
1、速度慢
2酸些、不走回頭路
6宰译、迭代器和可迭代對(duì)象的對(duì)比:
可迭代對(duì)象是一個(gè)操作方法比較多,比較直觀魄懂,存儲(chǔ)數(shù)據(jù)相對(duì)少的一個(gè)數(shù)據(jù)集沿侈。
當(dāng)你側(cè)重于對(duì)于數(shù)據(jù)可以靈活處理,并且內(nèi)存空間足夠逢渔,將數(shù)據(jù)集設(shè)置為可迭代對(duì)象是明確的選擇肋坚。
迭代器是一個(gè)非常節(jié)省內(nèi)存,可以記錄取值位置肃廓,可以直接通過(guò)循環(huán)+next方法取值智厌,但是不直觀,操作方法比較單一的數(shù)據(jù)集盲赊。
當(dāng)你的數(shù)據(jù)量過(guò)大铣鹏,大到足以撐爆你的內(nèi)存或者你以節(jié)省內(nèi)存為首選因素時(shí),將數(shù)據(jù)集設(shè)置為迭代器是一個(gè)不錯(cuò)的選擇哀蘑。
7诚卸、while模擬for的內(nèi)部循環(huán)機(jī)制:
? ?for循環(huán)的循環(huán)對(duì)象一定要是可迭代對(duì)象,但是這不意味著可迭代對(duì)象就可以取值绘迁,因?yàn)閒or循環(huán)的內(nèi)部機(jī)制是:將可迭代對(duì)象轉(zhuǎn)換成迭代器合溺,然后利用next進(jìn)行取值,最后利用異常處理處理StopIteration拋出的異常缀台。
l1 = [1, 2, 3, 4, 5, 6]
# 1 將可迭代對(duì)象轉(zhuǎn)化成迭代器
obj = iter(l1)
# 2,利用while循環(huán)棠赛,next進(jìn)行取值
while 1:
? ? # 3,利用異常處理終止循環(huán)
? ? try:
? ? ? ? print(next(obj))
? ? except StopIteration:
? ? ? ? break