18. 再說迴圈~列表和迴圈的高階操作

大牧莫邪發表於2017-05-18

在前面的課程中,我們已經學習了迴圈和函式的基本操作,這節內容主要針對迴圈和函式在專案使用過程中的一些更加有使用價值的操作進行分析和講解

本節內容:

  • 迴圈部分

    • 列表構建器
    • 列表動態構建器
    • 迴圈操作序列物件
    • 迴圈迭代遍歷資料
  • 函式部分

    • 函式遞迴
    • 引數使用函式
    • 函式中返回函式
    • 匿名函式
    • 偏函式

1. 迴圈操作

1.1 列表構建器

常規情況下,我們定義列表的語法如下 ```

lix = ["列表元素列表"]

如果在某些情況下,我們要定義一個1~100的列表,是一件特別麻煩的事情,手工編碼就會變得非常的繁瑣,此時,我們可以使用第一種方式來進行列表的構建

lix = list(range(1, 101))
執行結果:lix = [1, 2, 3, 4, 5, 6, ......]

但是,此時如果我們想要的不是自然數,而是每個數字的平方呢? 我們可以這麼做

lix = [];
for x in range(1, 101):
    lix.push(x ** 2)
執行結果:lix = [1,4,9,16,25.....]

```

但是通過這樣的方式迴圈迭代比較繁瑣,可以通過列表構建器來直接實現 ```

lix = [x * x  for x in range(1, 101)]
執行結果:lix = [1,4,9,16,25.....]
# 其實列表構建器中,就是一個簡單的表示式操作

```

同樣的,在列表構建器的表示式中,可以新增簡單的條件處理 ```

lix = [x * x for x in range(1, 101) if x % 2 == 0]
執行結果:lix = [4,16,36.....]

```

也可以在迴圈過程中,來使用多層迴圈巢狀,實現更加複雜的效果 ```

lix = [x + y  for x in "abc" for y in "xyz"]
執行結果:['ax', 'ay', 'az', 'bx', 'by', 'bz', 'cx', 'cy', 'cz']

```

1.2 列表動態構建器

但是我們通過前面的學習已經知道,這些資料都是載入到記憶體中的,如果列表中的資料量比較大的情況下,記憶體消耗是比較嚴重的 在某些情況下,我們只需要使用列表中的一部分資料,後面的資料並不是特別關心,如:通過列表來記錄一個符合某種規則的序列,每次我們只是關心下一個資料,並不關心後面的N條資料,應該怎麼做呢?比如我們需要一個奇數列表 ```

# 常規構建器的做法
lix = [2*x + 1 for x in range(1, 101)]
# 執行結果:[1,3,5,7,9,11,13,15,17.....]
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
# 常規構建器可以直接構建生成
# 但是存在問題,如果一次構建的資料量太大,會嚴重佔用記憶體
# 我們在使用該列表的時候,有可能只是使用前10項
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
# 使用列表動態構建器
lix = (2 * x - 1 for x in range(1, 101))
# 執行結果:print (lix) --> <generator object <genexpr> at 0x7f232e462048>
next(lix)
# 執行結果:1
next(lix)
# 執行結果:3
next(lix)
# 執行結果:5
next(lix)
# 執行結果:7
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
# 列表動態構建器
# 和構建器基本沒有區別,建立的時候列表中是沒有資料的
# 必須通過next()函式來獲取列表中的下一條資料
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

```

1.3. 迴圈列表

常規迴圈列表的方式 ```

lix = ["遠古巫靈澤拉斯", "機械先驅維克托", "懲戒之箭維魯斯", "龍血武姬希瓦娜"]
for x in lix:
    print(x)
執行結果:
遠古巫靈澤拉斯
機械先驅維克托
懲戒之箭維魯斯
龍血武姬希瓦娜

如果此時,我想象其他語言一樣,在迴圈過程中操作當前正在迴圈的元素的下標呢? 可以通過enumerate()函式對列表進行處理

lix = ["遠古巫靈澤拉斯", "機械先驅維克托", "懲戒之箭維魯斯", "龍血武姬希瓦娜"]
for index, item in enumerate(lix):
    print(index, item)
執行結果:
0 遠古巫靈澤拉斯
1 機械先驅維克托
2 懲戒之箭維魯斯
3 龍血武姬希瓦娜

```

1.4. 迴圈字典

因為列表、元組、集合中儲存的都是一個個獨立的元素,對列表的迴圈比較簡單 那麼如果迴圈key:value鍵值對的字典應該怎麼做呢

我們回顧一下字典中常用的一些函式 dict.items();返回字典中的每一組key:value資料 dict.keys();返回字典中的所有的key組成的集合 dict.values();返回字典中所有的value組成的列表 ```

lid = {"遠古巫靈":"澤拉斯", "機械先驅":"維克托", "懲戒之箭":"維魯斯", "龍血武姬":"希瓦娜"}
# 通過keys()迴圈遍歷字典的key
for k in lid.keys():
    print(k)
# 通過values()迴圈遍歷字典的value
for v in lid.values():
    print(v)
# 通過items()迴圈遍歷所有的字典資料
for k, v in lid.items():
    print(k, v)

```

1.5. 迴圈判斷

最後我們需要補充一個非常重要的東西,通常情況,我們對於python中的序列物件可以進行迴圈處理,那麼首先需要判斷一下我們要處理的資料是不是迴圈,如果不是迴圈就會出現錯誤 ```

# 迴圈字串
s1 = "abc"
for x in s1:
    print(x)
# 執行結果
~a
~b
~c
# 迴圈整數
s2 = 100;
for x in s2:
    print(x)
# 執行結果:出現報錯提示int物件不是iterable
~Traceback (most recent call last):
~File "<stdin>", line 1, in <module>
~TypeError: 'int' object is not iterable

我們看到,對於非序列物件,出現物件不是iterable的錯誤提示 iterable是Python中的迭代物件,序列物件一般都是迭代物件 那怎麼判斷一個物件是否迭代物件呢?

# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
# 判斷一個物件是否iterable迭代物件
# 首先通過from collections import Iterable語句來在當前
# python檔案中引入collections模組中的Iterable型別
# 然後通過isinstance來判斷我們要迴圈的物件是否Iterable物件
# * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
s1 = "abc",
s2 = [1,2,3,4]
s3 = (1,2,3,4)
s4 = {1,2,3,4}
s5 = {"1":"a", "2":"b", "3":"c"}
s6 = 100
執行結果
>>> isinstance(s1, Iterable)
True
>>> isinstance(s2, Iterable)
True
>>> isinstance(s3, Iterable)
True
>>> isinstance(s4, Iterable)
True
>>> isinstance(s5, Iterable)
True
>>> isinstance(s6, Iterable)
False

那這樣就好辦了,如果我們要遍歷指定的資料,首先判斷是否是迭代物件,是迭代物件我們再進行迭代操作就可以了

# 匯入collections模組中的Iterable物件
from collections import Iterable
# 遍歷資料
s1 = [1,2,3,4]
if isinstance(s1, Iterable):
    for x in s1:
        print(x)

s2 = 10000
if isinstance(s2, Iterable):
    for x in s2:
        print(x)
# 執行結果不會出現報錯了

```

本節內容主要講解了實際專案中經常用到的序列物件列表的高階使用方式,以及使用for迴圈進行序列物件迴圈遍歷過程中的幾種特殊的使用方式。下節內容,我們繼續說另一個學過的東東~函式的高階操作方式。

相關文章