1. 程式人生 > >Python——while和for循環

Python——while和for循環

found BE 進行 AC 閱讀 解包 rate sha 但是

while 循環

一般格式:

[python] view plain copy
while <test>:  
    <statements1>  
else <test>:  
    <statements2>  
else為可選部分,當控制權離開循環而又沒有碰到break語句時會執行。
[python] view plain copy
>>> x = ‘spam‘  
>>> while x :  
    print (x,end=‘ ‘)  
    x = x[1:]  
  
      
spam pam am m   
註意:這裏使用end = ‘ ‘關鍵字參數,使所有輸出都出現在同一行,之間用空格隔開
------------------------------------------------------------------------------------------------------------------------------------------------
break、continue、pass和循環else

break:跳出最近所在的循環(跳過整個循環語句)
continue:跳到最近所在循環的開頭處(來到循環的首行)
pass:什麽事也不做,只是空占位語句
循環else塊:只有當循環正常離開時才會執行(也就是沒有碰到break語句)

------------------------------------------------------------------------------------------------------------------------------------------------

一般循環格式

加入break和continue後,while的一般循環格式變為:

[python] view plain copy
while <test1>:  
    <statements1>  
    if <test2>:break  
    if <test3>:continue  
else:  
    <statements2>  
------------------------------------------------------------------------------------------------------------------------------------------------
pass語句是無運算的占位語句,當語法需要語句並且還沒有任何使用的語句可寫時,就可以使用它。它通常用於為復合語句編寫一個空的主體。例如,如果想寫個無限循環,每次叠代什麽也不做,就寫個pass
[python] view plain copy
>>> while True :pass  
因為主體只是空語句,Python陷入了死循環,這個程序並沒有什麽用處。以後將會看到它更有意義的用處。例如,忽略try語句所捕獲的異常,以及定義帶屬性的空類對象,而該類實現的對象行為就像其他語言的結構和記錄。pass有時指的是“以後會填上”,只是暫時用於填充函數主體而已
[python] view plain copy
def func1():  
    pass  
  
def func2():  
    pass  
我們無法保持函數體為空而不產生語法錯誤,因此,可以使用pass來替代
【另外:在Python3.0以後,程序中可以使用三個點...來代替pass,這樣似乎更加簡潔明了】
------------------------------------------------------------------------------------------------------------------------------------------------

continue語句會立即跳到循環的頂端,即跳過本次循環,執行下一次循環

break 語句會立即離開循環

[python] view plain copy
>>> while True:  
    name = input(‘Enter name:‘)  
    if name == ‘stop‘:break  
    age = input(‘Enter age:‘)  
    print(‘Hello‘,name,‘=>‘,int(age)**2)  
  
      
Enter name:Gavin  
Enter age:2  
Hello Gavin => 4  
Enter name:Spam  
Enter age:20  
Hello Spam => 400  
Enter name:stop  
------------------------------------------------------------------------------------------------------------------------------------------------
循環else
和循環else子句結合時,break語句通常可以忽略其他語言中所需要的搜索狀態標誌位。

例如,下列程序搜索大於1的因子,來決定正整數y是否為質數:

[python] view plain copy
>>> def judge(y):  
    x = y//2  
    while x >1:  
        if y % x ==0:  
            print(y,‘has factor‘,x)  
            break  
        x -= 1  
    else:  
        print(y,‘is prime‘)  
  
          
>>> judge(8)  
8 has factor 4  
>>> judge(19)  
19 is prime  
>>> judge(119)  
119 has factor 17  
除了設置標誌位在循環結束時進行測試外,也可以在找到因子時插入break。這樣一來,循環else分句可以視為只有當沒有找到因子時才會執行。如果你沒有碰到break,該數就是質數。
【註意,當第一次判斷while循環條件就不滿足時,也就是一次循環也沒有進行時,還是會執行else子句的】
=================================================================================

for循環

一般用法:

[python] view plain copy
for <target> in <object>:  
    <statements>  
else:  
    <statements>  
當python運行for循環時,會逐個將序列對象中的元素賦值給目標,然後為每個元素執行循環主體。
for循環也可以用break、continue和else子句

完整格式如下:

[python] view plain copy
for <target>  in <object>:  
    <statements>  
    if <test>:break  
    if <test>:continue  
else:  
    <statements>  
------------------------------------------------------------------------------------------------------------------------------------------------
基礎應用:
[python] view plain copy
>>> for x in [‘spam‘,‘eggs‘,‘ham‘]:  
    print(x,end=  ‘ ‘)  
  
      
spam eggs ham  
下面兩個例子會計算列表得到所有元素的和與乘積。
[python] view plain copy
>>> s = 0  
>>> for x in [1,2,3,4]:  
    s += x  
  
      
>>> x  #這裏x這個變量依然是有值的  
4  
>>> s  
10  
[python] view plain copy
>>> p = 1  
>>> for x in [1,2,3,4]:  
    p *= x  
  
      
>>> p  
24  
在以後,還會知道Python有一些工具,可以自動對列表中的元素應用諸如‘+’和‘*‘類似的運算,但是使用for循環通常也一樣簡單
------------------------------------------------------------------------------------------------------------------------------------------------
其他數據類型
不止對於列表適用,for循環對任何序列都適用,for循環還可以應用於字符串和元組,這裏就不舉例了。
實際上,for循環甚至可以應用在一些根本不是序列的對象上,對於文件和字典也有效。
------------------------------------------------------------------------------------------------------------------------------------------------

在for 循環中的元組賦值

[python] view plain copy
>>> T = [(1,2),(3,4),(5,6)]  
>>> for (a,b) in T:  
    print(a,b)  
  
      
1 2  
3 4  
5 6  
[python] view plain copy
>>> for x in T :  
    print(x)  
  
      
(1, 2)  
(3, 4)  
(5, 6)  
註意上述兩個例子的區別。第一個例子可以看做元組解包的賦值運算
這種形式通常和我們將要介紹的zip調用一起使用,以實現並行遍歷。在Python中,它通常還和SQL數據庫一起使用,其中,查詢結果表作為這裏使用的列表這樣的序列的序列而返回——外圍的列表就是數據庫表,嵌套的元組是表中的行,元組賦值和列對應
for 循環中的元組使得用items方法來遍歷字典中的鍵和值變得很方便,而不必再遍歷鍵並手動索引以獲取值:

[python] view plain copy
>>> D = {‘a‘:1,‘b‘:2,‘c‘:3}  
>>> for key in D:  
    print(key,‘=>‘,D[key])  
  
      
b => 2  
c => 3  
a => 1  
[python] view plain copy
>>> list(D.items())  
[(‘b‘, 2), (‘c‘, 3), (‘a‘, 1)]  
>>> for (key,value) in D.items():  
    print(key,‘=>‘,value)  
  
      
b => 2  
c => 3  
a => 1  
註意for循環中的元組賦值並非一種特殊情況,這一點很重要;單詞for之後的任何賦值目標在語法上都是有效的。盡管我們總是在for循環中手動地賦值以解包:
[python] view plain copy
>>> for both in T:  
    a,b = both  
    print(a,b)  
  
      
1 2  
3 4  
5 6  
------------------------------------------------------------------------------------------------------------------------------------------------
Python3.0 在for循環中擴展的序列賦值

實際上,for循環中的循環變量真的可以是任何賦值目標,在這裏,也可以使用Python3.0的擴展序列解包賦值語法,來提取序列中的序列的元素和部分。

擴展序列賦值可以參考這裏
------------------------------------------------------------------------------------------------------------------------------------------------

嵌套for循環

這段代碼會在對象列表中搜索每個鍵,然後報告其搜索結果:

[python] view plain copy
>>> items = [‘aaa‘,111,(4,5),2.01]  
>>> tests = [(4,5),3.14]  
>>> for key in tests:  
    for item in items:  
        if key == item:  
            print(key,‘was found‘)  
            break  
    else:  
        print(key,‘not found‘)  
  
          
(4, 5) was found  
3.14 not found  
=================================================================================
編寫循環的技巧
1.內置range函數返回一系列連續增加的整數,可作為for中的索引
2.內置zip函數返回並行元素的元組的列表,可用於在for中內遍歷整個序列。
------------------------------------------------------------------------------------------------------------------------------------------------

循環計數器:while和range

range函數是通用的工具,可用在各種環境中,雖然range常用在for循環中來產生索引,但也可以用在任何需要整數列表的地方。在Python3.0中,range是一個叠代器,會根據需要產生元素,因此,我們需要將其包含到一個list調用中以一次性顯示其結果:

[python] view plain copy
>>> list(range(5)),list(range(2,5)),list(range(0,10,2))  
([0, 1, 2, 3, 4], [2, 3, 4], [0, 2, 4, 6, 8])  
一個參數時,range會產生從零算起的整數列表,但其中不包括該參數的值;
如果傳進兩個參數,第一個視為下邊界。
第三個選用參數可以提供步進值,使用時,Python會對每個連續整數加上步進值(步進值默認為1).
range也可以是非正數或非遞增的:
[python] view plain copy
>>> list(range(-5,5))  
[-5, -4, -3, -2, -1, 0, 1, 2, 3, 4]  
>>> list(range(5,-5,-2))  
[5, 3, 1, -1, -3]  
從內部實現上來看,for循環以這種方式使用時,會自動處理叠代的細節。如果你真的想要明確得掌控索引邏輯,可以用while循環來實現:
[python] view plain copy
>>> s = ‘gavin‘  
>>> i = 0  
>>> while i<len(s):  
    print(s[i],end = ‘ ‘)  
    i+=1  
  
g a v i n   
------------------------------------------------------------------------------------------------------------------------------------------------
非完備遍歷:range和分片
一般情況下,在對序列進行遍歷時,最好使用Python中的簡單的for循環,不要使用while,並且不要在for循環中使用range調用,只將其視為最後的手段。

[python] view plain copy
>>> for item in X:print(item)  
然而利用range進行索引的用處是,我們可以通過控制range來實現特殊的遍歷,例如,在遍歷的過程中跳過一些元素
[python] view plain copy
>>> S = ‘abcdefghijklmn‘  
>>> for i in range(0,len(S),2):print(S[i],end = ‘ ‘)  
  
a c e g i k m   
在這裏,我們通過所產生的range列表,訪問了字符串S中每隔一個的元素,要使用每隔兩個的元素,可以把range的第三個參數改為3,以此類推。

然而,這可能不是如今Python中最理想情況下實現的技術,如果你真想跳過序列中的元素,可以用前面介紹的擴展的第三個限制值形式的分片表達式,例如,要使用S中每隔一個的字符串,可以用步進值2來分片:
[python] view plain copy
>>> for item in S[::2]:print(item,end=‘ ‘)  
  
a c e g i k m  
結果是相同的,但對我們來說更容易編寫,對其他人來說,更容易閱讀。
------------------------------------------------------------------------------------------------------------------------------------------------
修改列表:range

可以使用range和for的組合的常見場合就是在循環中遍歷列表時對其進行修改。例如,假設你因某種理由要為列表中的每個元素都加1,你可以通過簡單的for循環來做,但結果可能不是你想要的:

[python] view plain copy
>>> L = [1,2,3,4,5]  
>>> for x in L:  
    x+=1  
  
      
>>> L  
[1, 2, 3, 4, 5]  
>>> x  
6  
這樣並不行,因為修改的是循環變量x,而不是列表L.
要真的在我們遍歷列表時對其修改,我們需要使用索引,讓我們可以在遍歷時替每個位置賦一個一個已更新的值。range/len組合可以替我們產生所需要的索引。
[python] view plain copy
>>> L = [1,2,3,4,5]  
>>> for i in range(len(L)):  
    L[i] +=1  
  
      
>>> L  
[2, 3, 4, 5, 6]  
用while循環也可以做,只是運行比較慢。
[python] view plain copy
[x+1 for x in L]  
這種形式的列表解析表達式也能做類似的工作,而且沒有對最初的列表進行在原處的修改(我們可以把表達式的新列表對象賦值給L,但是這樣不會更新原始列表的其他任何引用值)。因為這是循環的核心概念,我們將在以後對列表解析做一個完整的介紹。
------------------------------------------------------------------------------------------------------------------------------------------------
並行遍歷:zip和map
內置zip函數可以讓我們使用for循環來並行使用多個序列,在基本運算中,zip會取得一個或多個序列為參數,然後返回元組的列表,將這些序列中的並排的元素配成對

例如,假設我們要使用兩個列表:

[python] view plain copy
>>> A = [1,2,3,4]  
>>> B = [11,22,33,44]  
要合並這些列表中的元素,我們可以使用zip來創建一個元組對的列表(和range一樣,zip在Python3.0中也是一個可叠代對象,因此,我們必須將其包含在一個list調用中以便一次性顯示所有結果)
[python] view plain copy
>>> C = zip(A,B)  
>>> C  
<zip object at 0x0405BE18>  
>>> list(C)  
[(1, 11), (2, 22), (3, 33), (4, 44)]  
這樣的結果在其他環境下也有用,然而搭配for循環中,它就會支持並行叠代:
[python] view plain copy
>>> for (x,y) in zip(A,B):  
    print(x,y,‘---‘,x+y)  
  
      
1 11 --- 12  
2 22 --- 24  
3 33 --- 36  
4 44 --- 48  
zip可以接受任何類型的序列(其實就是任何可叠代的對象,包括文件),並且可以有兩個以上的參數。例如
[python] view plain copy
>>> T1,T2,T3 = (1,2,3),(4,5,6),(7,8,9)  
>>> T2  
(4, 5, 6)  
>>> list(zip(T1,T2,T3))  
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]  
當參數長度不同時,zip會以最短序列的長度為準來截斷所得到的元組:
[python] view plain copy
>>> S1 = ‘abc‘  
>>> S2 = ‘xyz123‘  
>>> list(zip(S1,S2))  
[(‘a‘, ‘x‘), (‘b‘, ‘y‘), (‘c‘, ‘z‘)]  
------------------------------------------------------------------------------------------------------------------------------------------------
使用zip構造字典
前面介紹過,當鍵和值的集合必須在運行時計算時,這裏所用的zip調用也可用於產生字典,並且非常方便。

假設有下列的鍵和值的列表:

[python] view plain copy
>>> keys = [‘spam‘,‘eggs‘,‘toast‘]  
>>> vals=[1,2,3]  
將這些列表變成字典的一種做法就是將這些字符zip起來,並通過for循環並行步進處理:
[python] view plain copy
>>> list(zip(keys,vals))  
[(‘spam‘, 1), (‘eggs‘, 2), (‘toast‘, 3)]  
>>> D2 = {}  
>>> for (key,val) in zip(keys,vals):  
    D2[key] = val  
  
      
>>> D2  
{‘toast‘: 3, ‘spam‘: 1, ‘eggs‘: 2}  
不過,在Python2.2和後續版本中,可以完全跳過for循環,直接把zip過的鍵/值列表傳給內置的dict構造函數:
[python] view plain copy
>>> D3 = dict(zip(keys,vals))  
>>> D3  
{‘toast‘: 3, ‘spam‘: 1, ‘eggs‘: 2}  
------------------------------------------------------------------------------------------------------------------------------------------------

產生偏移和元素:enumerate

之前,我們討論過通過range來產生字符串中元素的偏移值,而不是那些偏移處的元素,不過,在有些程序中,我們兩者都需要:需要的元素以及這個元素的偏移值。

可以按照下面這個簡單的例子做:

[python] view plain copy
>>> S = ‘spam‘  
>>> offset = 0  
>>> for item in S:  
    print(item,‘appears at offset‘,offset)  
    offset += 1  
  
      
s appears at offset 0  
p appears at offset 1  
a appears at offset 2  
m appears at offset 3  
不過內置函數enumerate可以為我們做這件事情:
[python] view plain copy
>>> S = ‘spam‘  
>>> for (offset,item) in enumerate(S):  
    print(item,‘appears at offset‘,offset)  
  
      
s appears at offset 0  
p appears at offset 1  
a appears at offset 2  
m appears at offset 3  
可以看到:
[python] view plain copy
>>> enumerate(S)  
<enumerate object at 0x03602FA8>  
>>> list(enumerate(S))  
[(0, ‘s‘), (1, ‘p‘), (2, ‘a‘), (3, ‘m‘)]  
enumerate函數返回一個生成器對象:這種對象支持接下來要學習的叠代協議。簡而言之,這個對象有一個__next__方法,由下一個內置函數調用它,並且在循環中每次叠代的時候它會返回一個(index,value)的元祖。我們可以在for循環中通過元組賦值將元組解包(很像是使用zip)
[python] view plain copy
>>> E = enumerate(S)  
>>> E  
<enumerate object at 0x03602F80>  
>>> next(E)  
(0, ‘s‘)  
>>> next(E)  
(1, ‘p‘)  
>>> next(E)  
(2, ‘a‘)  
[python] view plain copy
>>> [c*i for (i,c) in enumerate(S)]  
[‘‘, ‘p‘, ‘aa‘, ‘mmm‘]  

  

Python——while和for循環