python 標準類型之List
List可以說是python標準類型中用的最頻繁的類型。記得大一剛學C語言的時候,不知到怎麼把幾個不同的數據對象,放到同一個數組或者鏈表中,問了老師也沒找到解決方法,直到後來遇到了 void* 。而在python裏面,用List便可輕鬆實現,可見使用弱類型的語言有時可能比使用強類型的語言,能夠提高不少效率。
>>> li = ["a", "b", "mpilgrim", "z", "example"] 1
>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li[0] 2
'a'
>>> li[4] 3
'example'
1 首先我們定義了一個有 5 個元素的 list。注意它們保持着初始的順序。這不是偶然。List 是一個用方括號包括起來的有序元素的集合。
2 List 可以作爲以 0 下標開始的數組。任何一個非空 list 的第一個元素總是 li[0]。
3 這個包含 5 個元素 list 的最後一個元素是 li[4], 因爲列表總是從 0 開始。
負的 list 索引
>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li[-1] 1
'example'
>>> li[-3] 2
'mpilgrim'
1 負數索引從 list 的尾部開始向前計數來存取元素。任何一個非空的 list 最後一個元素總是 li[-1]。
2 如果負數索引使您感到糊塗, 可以這樣理解: li[-n] == li[len(li) - n]。 所以在這個 list 裏, li[-3] == li[5 - 3] == li[2]。
list 的分片(slice)
>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li[1:3] 1
['b', 'mpilgrim']
>>> li[1:-1] 2
['b', 'mpilgrim', 'z']
>>> li[0:3] 3
['a', 'b', 'mpilgrim']
1 您可以通過指定 2 個索引得到 list 的子集, 叫做一個 “slice” 。返回值是一個新的 list, 它包含了 list 中按順序從第一個 slice 索引 (這裏爲 li[1]) 開始, 直到但是不包括第二個 slice 索引 (這裏爲 li[3]) 的所有元素。
2 如果一個或兩個 slice 索引是負數, slice 也可以工作。如果對您有幫助, 您可以這樣理解:從左向右閱讀 list, 第一個 slice 索引指定了您想要的第一個元素, 第二個 slice 索引指定了第一個您不想要的元素。返回的值爲在其間的每個元素。
3 List 從 0 開始, 所以 li[0:3] 返回 list 的前 3 個元素, 從 li[0] 開始, 直到但不包括 li[3]。
Slice 簡寫
>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li[:3] 1
['a', 'b', 'mpilgrim']
>>> li[3:] 2 3
['z', 'example']
>>> li[:] 4
['a', 'b', 'mpilgrim', 'z', 'example']
1 如果左側分片索引爲 0, 您可以將其省略, 默認爲 0。所以 li[:3] 同 例 3.8 “list 的分片(slice)” 的 li[0:3] 是一樣的。
2 同樣的, 如果右側分片索引是 list 的長度, 可以將其省略。所以 li[3:] 同 li[3:5] 是一樣的, 因爲這個 list 有 5 個元素。
3 請注意這裏的對稱性。在這個包含 5 個元素的 list 中, li[:3] 返回前 3 個元素, 而 li[3:] 返回後 2 個元素。實際上, li[:n] 總是返回前 n 個元素, 而 li[n:] 將返回剩下的元素, 不管 list 有多長。
4 如果將兩個分片索引全部省略, 這將包括 list 的所有元素。但是與原始的名爲 li 的 list 不同, 它是一個新 list, 恰好擁有與 li 一樣的全部元素。li[:] 是生成一個 list 完全拷貝的一個簡寫。
向 list 中增加元素
>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li.append("new") 1
>>> li
['a', 'b', 'mpilgrim', 'z', 'example', 'new']
>>> li.insert(2, "new") 2
>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new']
>>> li.extend(["two", "elements"]) 3
>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', 'two', 'elements']
1 append 向 list 的末尾追加單個元素。
2 insert 將單個元素插入到 list 中。數值參數是插入點的索引。請注意, list 中的元素不必唯一, 現在有兩個獨立的元素具有 'new' 這個值, li[2] 和 li[6]。
3 extend 用來連接 list。請注意不要使用多個參數來調用 extend, 要使用一個 list 參數進行調用。在本例中, 這個 list 有兩個元素。
extend (擴展) 與 append (追加)的差別
>>> li = ['a', 'b', 'c']
>>> li.extend(['d', 'e', 'f']) 1
>>> li
['a', 'b', 'c', 'd', 'e', 'f']
>>> len(li) 2
6
>>> li[-1]
'f'
>>> li = ['a', 'b', 'c']
>>> li.append(['d', 'e', 'f']) 3
>>> li
['a', 'b', 'c', ['d', 'e', 'f']]
>>> len(li) 4
4
>>> li[-1]
['d', 'e', 'f']
1 Lists 的兩個方法 extend 和 append 看起來類似, 但實際上完全不同。 extend 接受一個參數, 這個參數總是一個 list, 並且添加這個 list 中的每個元素到原 list 中。
2 在這裏 list 中有 3 個元素 ('a', 'b' 和 'c'), 並且使用另一個有 3 個元素 ('d', 'e' 和 'f') 的 list 擴展之, 因此新的 list 中有 6 個元素。
3 另一方面, append 接受一個參數, 這個參數可以是任何數據類型, 並且簡單地追加到 list 的尾部。 在這裏使用一個含有 3 個元素的 list 參數調用 append 方法。
4 原來包含 3 個元素的 list 現在包含 4 個元素。 爲什麼是 4 個元素呢? 因爲剛剛追加的最後一個元素 本身是個 list。 List 可以包含任何類型的數據, 也包括其他的 list。 這或許是您所要的結果, 或許不是。 如果您的意圖是 extend, 請不要使用 append。
在 list 中搜索
>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', 'two', 'elements']
>>> li.index("example") 1
5
>>> li.index("new") 2
2
>>> li.index("c") 3
Traceback (innermost last):
File "<interactive input>", line 1, in ?
ValueError: list.index(x): x not in list
>>> "c" in li 4
False
1 index 在 list 中查找一個值的首次出現並返回索引值。
2 index 在 list 中查找一個值的首次出現。 這裏 'new' 在 list 中出現了兩次, 在 li[2] 和 li[6], 但 index 只返回第一個索引, 2。
3 如果在 list 中沒有找到值, Python 會引發一個異常。這一點與大部分的語言截然不同, 大部分語言會返回某個無效索引。儘管這種處理可能令人討厭, 但它仍然是件好事, 因爲它說明您的程序會由於源代碼的問題而崩潰, 好於在後面當您使用無效索引而引起崩潰。
4 要測試一個值是否在 list 內, 使用 in, 如果值存在, 它返回 True, 否則返爲 False 。
注意
在 2.2.1 版本之前, Python 沒有單獨的布爾數據類型。 爲了彌補這一點, Python 在布爾環境 (如 if 語句) 中幾乎接受所有東西, 遵循下面的規則:
0 爲 false; 其它所有數值皆爲 true。
空串 ("") 爲 false; 其它所有字符串皆爲 true。
空 list ([]) 爲 false; 其它所有 list 皆爲 true。
空 tuple (()) 爲 false; 其它所有 tuple 皆爲 true。
空 dictionary ({}) 爲 false; 其它所有 dictionary 皆爲 true。
這些規則仍然適用於 Python 2.2.1 及其後續版本, 但現在您也可以使用真正的布爾值, 它的值或者爲 True 或者爲 False。 請注意第一個字母是大寫的;這些值如同在 Python 中的其它東西一樣都是大小寫敏感的。
從 list 中刪除元素
>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', 'two', 'elements']
>>> li.remove("z") 1
>>> li
['a', 'b', 'new', 'mpilgrim', 'example', 'new', 'two', 'elements']
>>> li.remove("new") 2
>>> li
['a', 'b', 'mpilgrim', 'example', 'new', 'two', 'elements']
>>> li.remove("c") 3
Traceback (innermost last):
File "<interactive input>", line 1, in ?
ValueError: list.remove(x): x not in list
>>> li.pop() 4
'elements'
>>> li
['a', 'b', 'mpilgrim', 'example', 'new', 'two']
1 remove 從 list 中刪除一個值的首次出現。
2 remove 僅僅 刪除一個值的首次出現。 在這裏, 'new' 在 list 中出現了兩次, 但 li.remove("new") 只刪除了 'new' 的首次出現。
3 如果在 list 中沒有找到值, Python 會引發一個異常來響應 index 方法。
4 pop 是一個有趣的東西。它會做兩件事: 刪除 list 的最後一個元素, 然後返回刪除元素的值。請注意, 這與 li[-1] 不同, 後者返回一個值但不改變 list 本身。也不同於 li.remove(value), 後者改變 list 但並不返回值。
使用 list 的運算符
>>> li = ['a', 'b', 'mpilgrim']
>>> li = li + ['example', 'new'] 1
>>> li
['a', 'b', 'mpilgrim', 'example', 'new']
>>> li += ['two'] 2
>>> li
['a', 'b', 'mpilgrim', 'example', 'new', 'two']
>>> li = [1, 2] * 3 3
>>> li
[1, 2, 1, 2, 1, 2]
1 Lists 也可以用 + 運算符連接起來。 list = list + otherlist 相當於 list.extend(otherlist)。 但 + 運算符把一個新 (連接後) 的 list 作爲值返回, 而 extend 只修改存在的 list。 也就是說, 對於大型 list 來說, extend 的執行速度要快一些。
2 Python 支持 += 運算符。 li += ['two'] 等同於 li.extend(['two'])。 += 運算符可用於 list, 字符串和整數, 並且它也可以被重載用於用戶自定義的類中 (更多關於類的內容參見 第 5 章)。
3 * 運算符可以作爲一個重複器作用於 list。 li = [1, 2] * 3 等同於 li = [1, 2] + [1, 2] + [1, 2], 即將三個 list 連接成一個。