1. 程式人生 > >Python基礎 | 關於“迴圈”那些事

Python基礎 | 關於“迴圈”那些事

目錄

  • for 迴圈
    • list
    • range
    • enumerate
    • zip
  • while 迴圈
    • while相當於if時
    • while充當for和if的混合體
  • 泛迴圈
    • 列表解析
    • map
    • 迭代器
    • 生成器
  • 迴圈的跳出和繼續
    • 單層迴圈
    • 巢狀迴圈

Python中常見的迴圈有兩類:

  • for
  • while

for 迴圈

list

list是最常見的可迭代物件,其他可迭代的物件例如 dict,set,file lines,string

for i in set((1,2,3)):
    print(i)

輸出:
1
2
3

import string

list_num = list(string.digits)

for i in list_num:
    # 輸出偶數
    if int(i)%2 == 0:
        print(i)

輸出:
0
2
4
6
8

range

range 有頭無尾,e.g. range(1,3)

實際得到的序列是(1,2)

for i in range(3):
    print(i)

輸出:
0
1
2

for i in range(1,9):
    # 輸出偶數
    if int(i)%2 == 0:
        print(i)

輸出:
2
4
6
8

enumerate

enumerate為迴圈的list加上index,這個index是編號是從0開始的

list_val = [1,2,3,5,8]
for idx,val in enumerate(list_val):
    print(idx,val)

輸出:
0 1
1 2
2 3
3 5
4 8

zip

同時遍歷兩個以上的list,並按順序打包

list_1 = string.digits[:3]
list_2 = string.ascii_lowercase[:3]
list_3 = string.ascii_uppercase[:3]

print(list_1,list_2,list_3)

輸出:
012 abc ABC

list_merge_1 = list(zip(list_1,list_2,list_3))
print(list_merge_1)

list_merge_2 = [i+j+k for (i,j,k) in zip(list_1,list_2,list_3)]
print(list_merge_2)

輸出:
[('0', 'a', 'A'), ('1', 'b', 'B'), ('2', 'c', 'C')]
['0aA', '1bB', '2cC']

# 元素組合
list_merge_3 = [i+j for i in list('123') for j in list('ABC')]

print(list_merge_3)

輸出:
['1A', '1B', '1C', '2A', '2B', '2C', '3A', '3B', '3C']

while 迴圈

while相當於for和if的結合體。

while不一定執行的是迴圈,有時候功能和if差不多,這個時候while的意義相當於如果條件為真,那就執行如下操作

while更多扮演for和if聯合的角色,相當於重複執行如下操作,知道判斷條件(會不斷變化)不再成立為止

while相當於if時

# 需要break的配合
x = 2

while(x>1):
    print('這個值大於1')
    
    break

輸出:
這個值大於1

while充當for和if的混合體

# 需要自增的index來配合

idx = 1

while(idx < 5):
    print(idx)
    
    idx += 1

輸出:
1
2
3
4

泛迴圈

如果將迴圈理解為按照順序遍歷一個序列。
除了用for、while還可以用其他函式達到“遍歷”的效果。

列表解析

本質還是迴圈,常見的for迴圈在語句上的表現是多行,而列表解析是一行

# 篩選奇數
num_odd = [i for i in range(1,10) if i%2==1]

print(num_odd)

輸出:
[1, 3, 5, 7, 9]

map

對序列中多個物件執行相同操作

list(map(lambda x:x**2,range(4)))

輸出:
[0, 1, 4, 9]

list_words = ['life','is','short','use','python']

list(map(lambda x:len(x),list_words))

輸出:
[4, 2, 5, 3, 6]

迭代器

變種的for迴圈

按順序將序列值一次“彈出”,同時被”彈出“的值移出序列

序列為空時,報錯StopIteration

vals_iter = iter(list(range(3)))

next(vals_iter)

輸出:
0

迭代器可以如上述舉例一樣是”有窮“的迭代,也可以是”無窮“的,比如自增序列(index為自然順序)

# 定義一個迭代器
class test_iter:
    def __init__(self):
        self.a = 1
        self.b = 1
        
    def __iter__(self):
        return self
 
    def __next__(self):
        x = self.a
        self.a, self.b = self.b, self.a+self.b
        return x
fb = test_iter()

for i in range(6):
    print(next(fb))

輸出:
1
1
2
3
5
8

生成器

生成器和迭代器的對比

相同點:

  • 從執行的結果看都是基於一定的規則”迭代“產生序列(無論是“無窮”系列還是“有窮”系列)
  • 都支援iter,next方法
  • “彈出”數值後,會清除已“彈出”的數值

不同點:

  • 生成器屬於迭代器中的一種
  • 在定義的時候,定義生成器就和定義函式一樣自然(同時會自動產生iter和next方法),而定義迭代器則主要通過iter,next來定義序列;
  • 更多參考1
  • 更多參考2
def num_even(x):
    while(x>0):
        if x%2 == 0:
            yield x
        x -= 1
x = num_even(9)

for i in x:
    print(i)

輸出:
8
6
4
2

迴圈的跳出和繼續

break 是跳出迴圈,也就是不再執行該迴圈的操作,如果是巢狀迴圈,那麼上層的迴圈也終止

continue 跳過當前的操作,進入下一輪迴圈,對上層的迴圈沒有影響

pass 接著執行,用得很少,此處不講

break,continue之後的語句也不會執行,所以一定要注意這兩個關鍵字放置的位置

單層迴圈

for i in range(5):
    print(i)
    
    if i == 2:
        break # 當i=2時,迴圈結束
        print('不會出現')   

輸出:
0
1
2

for i in range(5):
    
    if i == 2:
        continue # 跳過2這個值
        print('不會出現')   
    print(i)

輸出:
0
1
3
4

i = 1
while(i<5):
    print(i)
    break # 執行一次就結束
    print('不會出現')   

輸出:
1

i = 1
while(i<5):
    print(i)
    
    i += 1
    if i == 2:
        continue
        print('不會出現')   
    

輸出:
1
2
3
4

while中用continue要小心啊,比如如下程式碼是會一直執行的

i = 1
while(i<5):
    print(i)
    
    if i == 2:
        continue
        print('不會出現') 
        
    i += 1

巢狀迴圈

for i in range(3):
    for j in list('abc'):
        if j == 'b':
            break # 到b的時候就停止了
        print(i,j)

輸出:
0 a
1 a
2 a

for i in range(3):
    for j in list('abc'):
        if i == 1 or j=='b':
            continue
        print(i,j) #不會出現帶1和b的輸出值

輸出:
0 a
0 c
2 a