1. 程式人生 > >Python3學習(8)--迭代,可迭代的和迭代器

Python3學習(8)--迭代,可迭代的和迭代器

開始本篇之前,我們先來了解幾個單詞

        迭代:iteration

可迭代的:Iterable

    迭代器:iterator

從單詞我們可以看出來差異,可迭代的一看就是狀態詞,我們不做多說,下面會再講,而我們發現迭代和迭代器都是一個名詞表示,只不過迭代相比較迭代器更加抽象,這就好比,我們遍歷一個字典dict,用到for...in...的操作,我們稱之為在 迭代,而這種能遍歷的行為或者能迭代的行為我們稱之為可迭代的,而迭代器是具體到迭代行為的操作者或者說是實行者(感覺被賦予了生命一樣),在Python中有個函式專門返回的就是迭代器物件,而這個物件可以通過next的屬性對dict同樣進行遍歷,我們又稱這種現象為迭代器,如果你還是比較抽象的話,下面我就開始,直觀清晰的展現這三者之間的聯絡:

一、迭代(iteration)

如果給定一個list或tuple,我們要想訪問其中的某個元素,我們可以通過下標來,如果我們想要訪問所有的元素,那我們可以用for迴圈來遍歷這個list或者tuple,而這種遍歷我們就叫做迭代。

在Python中,迭代通過for..in..來完成,而其他大部分語言比如c和java,都是通過下標完成的。

比如java:

 for(int i=0;i<list.length;i++){
        n = list[i];
   }

再看Python:

for x in list:

        print(x)

 可以看出python的for迴圈抽象程式要高於java 的for迴圈,因為python的for迴圈不僅可以用在
 list和tuple上,還可以作用在其他可迭代的物件上(比如沒有下標的 dict):

#!/usr/bin/env python3
# -*- encoding:utf-8 -*-
#迭代字典dict
d={'name':'appleyk','age':26,'gender':'F','job':'coder'}

print(d)#首先輸出dict
print("迭代key")
for s in d:	
	print(s)

print("迭代value")
for value in d.values():
	print(value)
print('迭代key和value')
for k,v in d.items():
	print('key:%s,value:%s' %(k,v))

效果:


其實這種方式,像極了C#的foreach:

 string[] str = {"1","2","3","4"};
  foreach (string val in str) {
   Console.WriteLine(val);//1234
  }

事實上,字串也可以進行迭代,迭代出每個字元:
#!/usr/bin/env python3
# -*- encoding:utf-8 -*-
#迭代字典dict
'''
d={'name':'appleyk','age':26,'gender':'F','job':'coder'}

print(d)#首先輸出dict
print("迭代key")
for s in d:	#迭代key
	print(s)

print("迭代value")
for value in d.values():#迭代值value
	print(value)
print('迭代key和value')
for k,v in d.items():#迭代key和value
	print('key:%s,value:%s' %(k,v))
'''#多行註釋用 三個單引號

from __future__ import print_function #如果讓print輸出的內容不自動換行,我們可以匯入這個檔案

for ch in 'Hello World':
	print(ch,end='') #這樣的話,我們就可以原封不動的輸出Hello World 了
print("\nDone!")


二、可迭代的(Iterable

如果一個list、tuple或者一個字串可以遍歷,也就是有迭代的行為,我們稱之為是可以迭代的

比如,我們判斷一下,字串"ABC"是否是可迭代的,我們可以這樣做:

#!/usr/bin/env python3
# -*- encoding:utf-8 -*-



#判斷str是否可迭代
from collections import Iterable #如何判斷一個物件是否可迭代,通過collections模組的Iterable型別判斷

print('判斷\'ABC\'是否屬於可迭代的物件  :',isinstance('ABC',Iterable))
print('判斷123是否屬於可迭代的物件    :',isinstance(123,Iterable))
L = {1,2,3,4}
T = ('A','B','C','D')
D = {1:'A',2:'B',3:'C',4:'D'}
S = {"name","age","sex","adress"}
print('判斷list是否屬於可迭代的物件   :' ,isinstance(L,Iterable))
print('判斷tuple是否屬於可迭代的物件  :',isinstance(T,Iterable))
print('判斷dict是否屬於可迭代的物件   :' ,isinstance(D,Iterable))
print('判斷set是否屬於可迭代的物件    :' ,isinstance(S,Iterable))

當然,我們也可以判斷其他物件,比如說,一個int型別的數字是否是可迭代的,我們也可以乘此機會驗證下,我們學過的集合是不是都屬於可迭代的物件,下面,我們看下執行結果:


顯然,不是所有型別的物件都是可迭代的。

下面插播兩條知識點:

A、Python內建的enumerate函式可以把一個list變成 索引-元素對,這樣就可以在for迴圈中同時迭代索引(下標)和元素(key)本身

看個例子:

#!/usr/bin/env python3
# -*- encoding:utf-8 -*-

for index,value in enumerate(['first','second','third']):
	print(index,":",value)
print("上面是list,下面是dict")
for index,key in enumerate({'first':1,'second':2,'third':3}):
	print(index,":",key)
'''
for index,value in enumerate(('first','second','third')):
	print(index,":",value)
'''#當然tuple,字串等都是可以的,只要滿足可迭代,就可以這樣寫

執行結果:


B、對於迭代的物件是巢狀型的,我們也可以通過for..in..迴圈的方式取出每一個元素

比如,迭代的物件實際上是一個list,然而這個list的每一個元素竟然又是一個tuple,且每個tuple物件有N個元素,這樣的話,我們就不能單單通過 for x in list:的方式來取了,你可以大膽猜測一下,應該可以這樣寫,for N1,N2,N3...in list:,如果成立,則再次證明了我們的Python實在是簡單暴力又一次啊!,不多說,看demo:

#!/usr/bin/env python3
# -*- encoding:utf-8 -*-

for x,y,z in [(1,2,3),(4,5,6,),(7,8,9)]:
	print(x,y,z)
我們來看下執行結果:


如果,我們寫程式碼的時候不寫z會是什麼情況?


上面的報錯,大概意思是在說,我總過有三個女兒,要麼都娶走,要麼別來煩我(解壓出來的值與實際取走的值不匹配)

由此可見,python是很靈活的,播報到此結束,我們繼續。

三、迭代器(Iterator)

最開始說了什麼是迭代器,一種更具體的手段,通過next來訪問元素。

例子A:

我們定義一個list,並通過iter獲得list的迭代器物件

#!/usr/bin/env python3
# -*- encoding:utf-8 -*-

#摘要:
#任何可迭代的物件 都可以使用for迴圈列印,包括我們自定義的型別,只要符合迭代條件,就可以用for迴圈
#另外 注意 iterator 是迭代器的意思,而Iterable 是一個型別
#為什麼這麼說呢,迭代器 可以通過next來訪問元素,因為它不知道物件裡面有多少個元素
L = ['appleyk','F',26,'Python3']
it = iter(L) #獲得list的迭代器物件
while True:
		x=next(it)#然後我們用next對這個物件進行遍歷
		print(x)
	    #next會不會溢位呢?它會一直訪問停不下來嗎?

針對上面的問題,我們看下執行的結果:



為避免這種尷尬,我們讓next不到元素的時候,迴圈終止,這樣的話,我們就看不到異常資訊的出現了,我們改下demo:

#!/usr/bin/env python3
# -*- encoding:utf-8 -*-

#摘要:
#任何可迭代的物件 都可以使用for迴圈列印,包括我們自定義的型別,只要符合迭代條件,就可以用for迴圈
#另外 注意 iterator 是迭代器的意思,而Iterable 是一個型別
#為什麼這麼說呢,迭代器 可以通過next來訪問元素,因為它不知道物件裡面有多少個元素
L = ['appleyk','F',26,'Python3']
it = iter(L) #獲得list的迭代器物件
while True:
	try:#try 試圖捕獲異常
		x=next(it)
		print(x)
	except StopIteration:#當捕獲到迭代行為終止的時候,也就是無元素可以在next的時候,我們終止迴圈
		break
這樣,我們就可以成功的跳過next的bug行為(其實也不怨它,只能說明它埋頭苦幹,太敬業了)了,修改後執行結果如下:

本篇結束!

愚公移山,短期看是愚,長期看,就是造福子子孫孫,一人苦修得萬人甜;

寫部落格也是一樣,先苦後甜,總感覺寫出來,太費時間,費精力,每次寫都有種還沒寫完就想提交的衝動,但是都忍住了,半個小時的事情,不想拖到以後忘的一乾二淨的時候還要重頭來過,希望以後的以後,我們這些凡人的腦袋裡都能植入一顆記憶晶片,以解除學習的痛苦吧。