Python 清單

Python 提供一個名為「list」的最佳內建清單類型。清單常值會以方括號 [ ] 括住。清單的運作方式與字串類似,您可以使用 len() 函式及方括號 [ ],使用索引 0 的第一個元素來存取資料。(請參閱官方的 python.org 清單文件)。

  colors = ['red', 'blue', 'green']
  print(colors[0])    ## red
  print(colors[2])    ## green
  print(len(colors))  ## 3

「red」'blue 'green' 字串清單

在清單上使用 = 的賦值作業不會建立副本。相反地,指派會讓兩個變數指向記憶體中的一個清單。

  b = colors   ## Does not copy the list

同時的顏色和 b 指向一份清單

「空白清單」是空的括號 [ ]。「+」的作用是附加兩份清單,因此 [1, 2] + [3, 4] 會產生 [1, 2, 3, 4] (就像使用字串 + 一樣)。

FOR 和 IN

Python 的 *for* 和 *in* 結構非常實用,我們將首先使用清單來說明這兩個結構的用法。*for* 結構體 (for var in list) 是查看清單 (或其他集合) 中每個元素的簡單方法。請勿在迭代期間新增或移除清單中的項目。

  squares = [1, 4, 9, 16]
  sum = 0
  for num in squares:
    sum += num
  print(sum)  ## 30

如果您知道清單的種類,請在迴圈中使用變數名稱來擷取相關資訊,例如「num」、「name」或「url」。由於 Python 程式碼沒有其他語法可提醒您類型,因此變數名稱是您掌握程式運作情況的重要方式。(這有點誤導,隨著您對 Python 的瞭解越來越多,您會看到型別提示的參照,可讓您在函式定義中加入型別資訊。Python 在執行您的程式時不會使用這些類型提示。其他程式 (例如 IDE 或整合式開發環境) 和靜態分析工具 (例如 lint 工具/類型檢查器) 會使用這些資訊,驗證函式是否以相容的引數呼叫。

*in* 結構體本身就是測試元素是否出現在清單 (或其他集合) 中 (value in collection) 的簡單方法,可測試值是否在集合中,並傳回 True/False。

  list = ['larry', 'curly', 'moe']
  if 'curly' in list:
    print('yay') ## yay

for/in 結構在 Python 程式碼中非常常見,可用於清單以外的資料類型,因此您應該熟記這些結構的語法。你可能會因為其他語言的習慣,開始手動重複執行集合,但在 Python 中,你應該只使用 for/in。

您也可以使用 for/in 處理字串。字串會像是其字元清單一樣運作,因此 for ch in s: print(ch) 會列印字串中的所有字元。

範圍

範圍(n) 函式會產生數字 0、1、... n-1 和範圍(a, b) 會傳回 a、a+1、... b-1,但不含最後一個數字。結合 for 迴圈和 range() 函式,您就能建立傳統的數值 for 迴圈:

  ## print the numbers from 0 through 99
  for i in range(100):
    print(i)

有一個變化版本 xrange(),可避免在效能敏感的情況下建立整個清單的成本 (在 Python 3 中,range() 會提供良好的效能行為,因此您可以忘記 xrange())。

While 迴圈

Python 也提供標準的 while 迴圈,而 *break* 和 *continue* 陳述式的作用與 C++ 和 Java 相同,可變更最內層迴圈的流程。上述 for/in 迴圈可以解決清單內每個元素的疊代作業常見情況,但迴圈可讓您完全控制索引號碼。以下是用於存取清單內第 3 個元素的 when 迴圈:

  ## Access every 3rd element in a list
  i = 0
  while i < len(a):
    print(a[i])
    i = i + 3

清單方法

以下列舉其他常見的清單方法。

  • list.append(elem):將單一元素新增至清單結尾。常見錯誤:不會傳回新清單,只會修改原始清單。
  • list.insert(index, elem):在指定索引處插入元素,並將元素向右移動。
  • list.extend(list2) 會將 list2 中的元素新增至清單結尾。在清單上使用 + 或 += 的效果與使用 extend() 類似。
  • list.index(elem) -- 從清單的開頭搜尋指定元素,並傳回其索引。如果沒有顯示元素,就會擲回 ValueError (使用「in」檢查沒有 ValueError)。
  • list.remove(elem):搜尋指定元素的第一個例項,並移除該元素 (如果不存在,則擲回 ValueError)
  • list.sort():在原地排序清單 (不會傳回)。(建議使用稍後顯示的 sorted() 函式)。
  • list.reverse() -- 將現有的清單反轉 (不會傳回清單)
  • list.pop(index):移除並傳回指定索引的元素。如果省略索引,則會傳回最右側的元素 (大致等同於 append())。

請注意,這些是清單物件的*方法*,而 len() 是將清單 (或字串或其他) 做為引數的函式。

  list = ['larry', 'curly', 'moe']
  list.append('shemp')         ## append elem at end
  list.insert(0, 'xxx')        ## insert elem at index 0
  list.extend(['yyy', 'zzz'])  ## add list of elems at end
  print(list)  ## ['xxx', 'larry', 'curly', 'moe', 'shemp', 'yyy', 'zzz']
  print(list.index('curly'))    ## 2

  list.remove('curly')         ## search and remove that element
  list.pop(1)                  ## removes and returns 'larry'
  print(list)  ## ['xxx', 'moe', 'shemp', 'yyy', 'zzz']

常見錯誤:請注意,上述方法不會「傳回」已修改的清單,而是只會修改原始清單。

  list = [1, 2, 3]
  print(list.append(4))   ## NO, does not work, append() returns None
  ## Correct pattern:
  list.append(4)
  print(list)  ## [1, 2, 3, 4]

建立名單

常見的模式是先以空白清單 [] 開始,然後使用 append() 或 extend() 新增元素:

  list = []          ## Start as the empty list
  list.append('a')   ## Use append() to add elements
  list.append('b')

列出切片

Slice 的運作方式就像字串一樣,也可用於變更清單的子部分。

  list = ['a', 'b', 'c', 'd']
  print(list[1:-1])   ## ['b', 'c']
  list[0:2] = 'z'    ## replace ['a', 'b'] with ['z']
  print(list)         ## ['z', 'c', 'd']

練習:list1.py

如要練習本節的內容,請嘗試 list1.py 中不使用排序的練習題 (在基本練習中)。