2.7. 串列

串列(list)是一個可變、有序的值序列。與字串和位元組不同,串列可以容納任何型別的值,而且你可以就地更改、新增或移除項目。

2.7.1. 建立串列

中括號可建立串列字面值:

empty   = []
nums    = [1, 2, 3]
mixed   = [1, "two", 3.0, True, None]    # any types
nested  = [[1, 2], [3, 4], [5, 6]]       # lists of lists

list 建構函式能從任何可迭代物件建立串列:

>>> list("abc")
['a', 'b', 'c']
>>> list(range(5))
[0, 1, 2, 3, 4]

2.7.2. 長度、索引與切片

len() 會回傳項目的數量。索引與切片的運作方式與字串相同——位置從 0 開始,負索引從結尾算起,而超出有效範圍的切片會靜默地裁剪而不引發錯誤:

>>> nums = [10, 20, 30, 40, 50]
>>> len(nums)
5
>>> nums[0]
10
>>> nums[-1]
50
>>> nums[1:4]
[20, 30, 40]
由六個格子組成的串列,正索引 0..5 標示在上方, 負索引 -6..-1 標示在每個格子的下方。

正索引從前面算起;負索引從結尾算起。

切片語法是 Python 在背後建立的 slice 物件的簡寫。nums[1:4] 等同於 nums[slice(1, 4)]。你很少需要手動建構一個切片物件,但 slice() 偶爾很有用,可將切片儲存為一個值以便重複使用:

head = slice(0, 3)
print(nums[head])             # [10, 20, 30]
print(letters[head])          # first three letters, same slice

2.7.3. 變更串列

串列支援就地的索引賦值與切片賦值:

>>> nums = [10, 20, 30]
>>> nums[0] = 99
>>> nums
[99, 20, 30]
>>> nums[1:3] = [200, 300, 400]    # slice can change the length
>>> nums
[99, 200, 300, 400]

最常用的串列方法:

>>> nums = []
>>> nums.append(1)
>>> nums.extend([2, 3])
>>> nums.insert(0, 99)
>>> nums
[99, 1, 2, 3]
>>> nums.pop()
3
>>> nums.sort()
>>> nums
[1, 2, 99]

這些方法會就地修改串列並回傳 None。寫成

nums = nums.sort()    # nums is now None -- common bug

幾乎絕對不是你想要的結果;原本的 nums 確實已被排序,但接著賦值卻會用回傳值覆寫這個名稱。請將 nums.sort() 單獨寫成一行,或使用內建的 sorted() 取得一個新的已排序串列,而不變更原始串列。

2.7.4. 運算子

  • + 會將兩個串列串接成一個新串列。

  • * 會重複一個串列。

  • in 會測試成員是否存在。

>>> [1, 2] + [3, 4]
[1, 2, 3, 4]
>>> [0] * 5
[0, 0, 0, 0, 0]
>>> 3 in [1, 2, 3]
True

2.7.5. 迭代串列

for 迴圈會依序走訪各項目:

for n in [10, 20, 30]:
    print(n)

2.7.6. 別名與變更

串列在記憶體中是單一的值;多個名稱可以指向同一個串列。透過其中一個名稱進行的變更,會在所有指向同一串列的名稱中可見。

兩個變數 a 和 b 都指向同一個串列 物件;對 a 進行附加在 b 中也可見。

ab 都指向同一個串列。透過任一名稱進行變更,會改變其他每個名稱所看到的內容。

>>> a = [1, 2, 3]
>>> b = a
>>> a.append(4)
>>> b
[1, 2, 3, 4]                # same object, change is visible

若要建立一份獨立的副本,可對整個串列進行切片,或呼叫 list 建構函式:

>>> c = a[:]                # or list(a)
>>> a.append(5)
>>> c
[1, 2, 3, 4]                # c is unaffected

這只會複製最上層的串列;巢狀串列在原始串列與副本之間仍然是共用的。