Python之流程語句:分支、循環、List Comprehension

在Python中,一個程序區塊是使用冒號開頭,之后同一個區塊中要有相同的縮進,不能混用不同的空格數,也不可混用空格和Tab,Python 建議使用4個空格作為縮進。

if分支語句

if condition1:
    if condtion2:
        doSomething()
    else:
        doSomething()
elif condition:
    doSomething()
else:
    doSomething()

Python區塊定義的方式避免了像C/C++、Java等語言某些讀起來不明確的情況,比如:

if(condition1)
    if(condition2)
        doSomething()
else
    doSomething2()

看起來else好像是跟第一個if語句對應的,但實際上這些語言采用的是就近配對原則,是和第二個if語句對應的,Python中就沒有這個問題,是以語句縮進來對應的。

if condition:
    if condition2:
         do_something()
else :
    do_something2()
#else跟第一個if語句配對

if condition:
    if condition2:
         do_something()
    else :
        do_something2()
# else與第二個if配對

在Python中還有個 if...else 表達式:

# 判斷奇偶數
>>> num = 11
>>> print('{} 是 {}'.format(num, '奇數' if num % 2 else '偶數'))
11 是 奇數

當if條件滿足時,會返回if前面的值,若不滿足則返回else后面的值。


while 循環

Python 提供了while 循環,根據while語句后面的內容來判斷是否執行循環體:

while condition:
    do_something()
else
    do_something()

當判斷條件成立時,會執行while區塊,else是可選的,如果有else語句,不管條件成不成立都會執行else下的語句,若不想讓else執行就在while區塊中加入break語句中斷循環,最好還是不要使用,這樣容易產生混亂。

print('請輸入兩個數字')
a = int(input('數字 1 :'))
b = int(input('數字 2 :'))
while b != 0:
    r = a % b
    a = b
    b = r
    if a == 1:
        print('互質')
        break
else:
    print('最大公因數:', a)

還是下面的代碼比較直觀:

print('請輸入兩個數字')
a = int(input('數字 1 :'))
b = int(input('數字 2 :'))
while b != 0:
    r = a % b
    a = b
    b = r
    if a == 1:
        print('互質')
    else:
        print('最大公因數:', a)

for in 循環

若要按順序迭代某個序列(字符串,元組,列表),則可以使用for in 語句:

>>> num = ['a', 1, '2', '3']
>>> for i in num:
...     print(i)
... 
a
1
2
3

如果在迭代的時候需要使用到索引,則可以配合 range() 函數使用,range() 函數可以產生一個指定的數字范圍:

>>> for i in range(len(num)):
...     print(i, num[i])
... 
0 a
1 1
2 2
3 3

range() 函數的形式是 range(start, stop[, step]), start默認是0,step是步長默認為1。

也可以使用 zip() 函數,將兩個序列的各個元素像拉鏈一樣一一配對,它返回的是一個zip對象,這個對象并沒有包含真正配對的元素,具有惰性求值的特性(關于惰性求值請看我的另一篇文章:Python中的優化:惰性求值詳解),像range()函數也是產生一個range對象不是列表:

>>> zip([1,2,3],[4,5,6],[7,8,9])
<zip object at 0x108498e08>
>>> for i, j, k in zip([1,2,3],[4,5,6],[7,8,9]):
...     print(i, j, k)
... 
1 4 7
2 5 8
3 6 9

若真的要迭代時具有索引信息,建議使用 enumerate() 函數而不是 range() 函數,enumerate() 返回一個 enumerate 對象,也是惰性求值,可使用for in 進行迭代,enumerate 可用于獲取元組元素:

>>> num = [1,2,3,4,5,6]
>>> list(enumerate(num))
[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]

可以利用元組拆解的特性獲取索引信息:

>>> for i, j in enumerate(num):
...     print(i, j)
... 
0 1
1 2
2 3
3 4
4 5
5 6

只要是實現了__iter__() 方法的對象,都可以通過__iter__() 方法返回一個迭代器,這個迭代器可以使用for in語句來迭代,如:range、zip、enumerate對象,集合也實現了__iter__() 方法,因此也可以進行迭代,但是集合是無序的,每次的迭代結果順序都不一樣;字典也是可以迭代的,使用keys()、values()、items()方法,分別返回dict_keys、dict_values、dict_items對象,也都實現了__iter__() 方法,因此也可以使用for in進行迭代,如果直接對字典進行for in操作,默認對鍵進行迭代。


pass、break、continue

在某個區塊中,并不想執行任何程序語句或者稍后需要些什么語句,對于還沒打算編寫的區塊,可以加上個pass語句,只是用來維持代碼的完整性,將來可能會用到它,因為可能會做一些小測試,看看其他的代碼是否正常運行。break和continue都是用來跳出循環的,break是直接跳出循環不在進行循環操作,continue是中止本次循環,繼續進行下一輪的循環。

list comprehension

將一個列表進行操作轉為另外一個列表是很常見的操作,Python提供了 list comprehension 語句:

# 將數組元素平方
#一般做法:
>>> array = [1, 2, 3, 4]
>>> array2 = []
>>> for i in array:
...     array2.append(i ** 2)
... 
>>> print(array2)
[1, 4, 9, 16]
#list comprehension語句
>>> array = [1, 2, 3, 4]
>>> array2 = [i ** 2 for i in array]
>>> print(array2)
[1, 4, 9, 16]

可以看到代碼精簡了很多,上述語句逐一迭代出數組元素并賦值給i變量,之后執行for左邊的表達式運算,使用 [] 括起來,表示每次迭代的結果收集為一個列表。
list comprehension 還可以與條件判斷式結合,構成過濾的功能:

#篩選出數組中的奇數
>>> array = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
>>> new_array = [i for i in array if i % 2]
>>> print(new_array)
[1, 3, 5, 7, 9]

在上述代碼中,只有滿足了if條件才會執行for左邊的語句,然后并入數組中。
當然,它還可以嵌套使用,不過這樣可讀性會變低,簡單兩層的還可以,復雜的不推薦使用:

# 將二維矩陣轉為一維
>>> matrix = [
... [1,2,3],
... [4,5,6],
... [7,8,9]
... ]
>>> array = [e for row in matrix for e in row]
>>> print(array)
[1, 2, 3, 4, 5, 6, 7, 8, 9]

#得到兩個序列的排列組合
```python
>>> num1 = [1, 2, 3, 4]
>>> num2 = [1, 2, 3, 4]
>>> [(i ,j) for i in num1 for j in num2 ]
[(1, 1), (1, 2), (1, 3), (1, 4), (2, 1), (2, 2), (2, 3), (2, 4), (3, 1), (3, 2), (3, 3), (3, 4), (4, 1), (4, 2), (4, 3), (4, 4)]
>>> [word1 + word2 for word1 in 'hello' for word2 in 'world']
['hw', 'ho', 'hr', 'hl', 'hd', 'ew', 'eo', 'er', 'el', 'ed', 'lw', 'lo', 'lr', 'll', 'ld', 'lw', 'lo', 'lr', 'll', 'ld', 'ow', 'oo', 'or', 'ol', 'od']

在 list comprehension 兩邊放上[],會產生列表,如果數據很多,直接返回列表會占用太多內存,可以用() 取代 [] ,這樣就會創建一個generator對象,具有惰性求值的特性:

>>> num = (i for i in range(99999999999999999))
>>> num
<generator object <genexpr> at 0x106e29fc0>

list comprehension語句也可以用來創建集合,在語句兩邊放上{}:

>>> num = [1,2,3,4,5,6,7,8,9,0]
>>> {i for i in num if i % 2}
{1, 3, 5, 7, 9}

也可以用來創建字典,使用zip()函數將鍵值一一配對:

>>> keys = ['JYH', 'JY']
>>> values = ['123', '456']
>>> {key : value for key, value in zip(keys, values)}
{'JYH': '123', 'JY': '456'}

還可以用來創建元組,由于()會創建生成器,所以要換一種方式,將生成器表達式傳給tuple():

>>> tuple(i for i in range(10))
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

關于惰性求值請看我的另一篇文章:Python中的優化:惰性求值詳解

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容