4.1. 串列
在Python中有提供數個非常有用資料結構,並且也可以將這些資料結構根據需求組合成更雜複的資料結構。首先,要介紹的第一個資料結構是串列。當建立一個空的串列之後,可以對其做加入、插入、刪除或修改資料等對資料結構的操作。
建立串列
串列可以透過下列幾個方式建立。
>>> l = list()
>>> l
[]
>>> type(l)
<class 'list'>
>>> l = []
>>> l
[]
>>> l = [1, 2, 3, 4, 5]
>>> l
[1, 2, 3, 4, 5]
串列可以同時加入不同的資料類型。
>>> l = [1, 2, '3', '4', 5.0, 6.0]
>>> l
[1, 2, '3', '4', 5.0, 6.0]
串列中也可以包含其他串列 (i.e., list of list)。
>>> l = [[1, 2], ['3', '4'], [5.0, 6.0]]
>>> l
[[1, 2], ['3', '4'], [5.0, 6.0]]
串列中也可以包含不同資料類型及串列。
>>> l = [1, '2', 3.0, [4, '5', 6]]
>>> l
[1, '2', 3.0, [4, '5', 6]]
可以使用 +、* 等算術運算子來操作串列。
>>> l = [1, 2, 3]
>>> l += [4, 5, 6]
>>> l
[1, 2, 3, 4, 5, 6]
>>> l = [0]
>>> l *= 5
[0, 0, 0, 0, 0]
使用索引值「存取」資料
可以利用串列索引值來「存取」串列中特定的資料,其索引值的範圍為 0 到 len(l) - 1,當使用的索引值超過範圍則會產生錯誤訊息。
>>> l = [1, 2, 3]
>>> l[1]
2
>>> l[1] = 'a'
>>> l
[1, 'a', 3]
>>> l[3]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
使用 [ 開始: 結束: 間隔 ] 取得子串列
透過 [ 開始: 結束: 間隔 ] 可以取得一個串列的子串列。
>>> l = [1, 2, 3, 4, 5]
>>> l[0:3]
[1, 2, 3]
>>> l[:5]
[1, 2, 3, 4, 5]
>>> l[2:]
[3, 4, 5]
>>> l[1:4]
[2, 3, 4]
>>> l[0:5:2]
[1, 3, 5]
>>> l[1:5:2]
[2, 4]
>>> l[::2]
[1, 3, 5]
>>> l[:5:2]
[1, 3, 5]
>>> l[1::2]
[2, 4]
>>> l[-1::-1]
[5, 4, 3, 2, 1]
>>> l[::-2]
[5, 3, 1]
>>> l[-1:-6:-2]
[5, 3, 1]
串列的多重指派
如果串列長度在處理資料的過程中是固定不變時 (或可使用元組),可以使用重派指派將串列中的資料指派到多個變數。
>>> l = ['1', '100', 1000]
>>> a, b, c = l
>>> a
'1'
>>> b
'100'
>>> c
1000
使用 in 判斷資料是否在串列中
要判斷某一個資料是否在串列中時,可以使用 in 關鍵字來達成。
>>> l = [1, 2.0, '3', 4, 5]
>>> 1 in l
True
>>> 2.0 in l
True
>>> 2 in l
True
>>> '3' in l
True
>>> '4' in l
False
使用 len() 取得串列長度
使用 len() 可以取得一個串列的長度。
>>> l = [1, 2, 3, 4, 5]
>>> len(l)
5
使用 list() 取得字元串列
使用 list() 來取得一個字串中每一個字元的串列。
>>> l = list('Hello World!')
>>> l
['H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!']
使用 append() 加入資料
要將資料加入到串列中可以使用 append()。
>>> l = []
>>> l.append(1)
>>> l.append(2)
>>> l.append(3)
>>> l
[1, 2, 3]
使用 extend() 加入另一個串列
如果要加入的資料是另一個串列,則可以使用 extend() 或是「+=」等方式來達成。
>>> l = [1, 2, 3]
>>> l
[1, 2, 3]
>>> l.extend(['4', '5', 6.0])
>>> l
[1, 2, 3, '4', '5', 6.0]
>>> l += [7, 8.0, '9']
>>> l
[1, 2, 3, '4', '5', 6.0, 7, 8.0, '9']
使用 pop() 取出資料
使用 pop() 將串列中的最後一個資料取出,或是使用 pop(i) 將串列中索引值 i 的資料取出。
>>> l = [1, 2, 3]
>>> l
[1, 2, 3]
>>> l.pop()
3
>>> l
[1, 2]
>>> l.pop(0)
1
>>> l
[2]
>>> l.pop()
2
>>> l
[]
使用 del 關鍵字及 remove() 刪除資料
要刪除串列中的資料時,可以使用 del 關鍵字及串列索引值來剛除特定資料或刪除整個串列,使用 remove(x) 則是移除第一筆特定資料 x。
>>> l = [1, 2, 3, 4, 5]
>>> l
[1, 2, 3, 4, 5]
>>> del l[2]
>>> l
[1, 2, 4, 5]
>>> del l[4]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list assignment index out of range
>>> del l
>>> l
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'l' is not defined
>>> l = [1, 2, 3, 4, 1]
>>> l.remove(1)
>>> l
[2, 3, 4, 1]
使用 index() 得到資料索引值
使用 index(x)得到「第一筆」特定資料 x 的串列索引值。
>>> l = ['a', 'b', 'c', 'b']
>>> l.index('c')
2
>>> l.index('b')
1
>>> l.index('d')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: 'd' is not in list
使用 insert() 插入資料
使用 insert(i, x) 可以在串列索引值為 i 的位置插入特定資料 x。
>>> l = [1, 2, 3]
>>> l.insert(0, 4)
>>> l
[4, 1, 2, 3]
>>> l.insert(3, 5)
[4, 1, 2, 5, 3]
>>> l.insert(5, 6)
[4, 1, 2, 5, 3, 6]
>>> l.insert(7, 7)
[4, 1, 2, 5, 3, 6, 7]
使用 count() 計算資料個數
使用 count(x) 可以計算資料 x 在串列中的個數。
>>> l = [1, 1, 1, 2, 2, 3, 4]
>>> l.count(1)
3
>>> l.count(2)
2
>>> l.count(3)
1
>>> l.count(4)
1
>>> l.count(5)
0
使用 sort() 排序
使用 sort() 將串列中的資料由小排到大。
>>> l = [5, 4, 3.0, 2, 1]
>>> l.sort()
>>> l
[1, 2, 3.0, 4, 5]
>>> l = [1, 2.0, '3', 4, 5.0]
>>> l.sort()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: str() < float()
使用 reverse() 反轉串列
使用 reverse() 反轉串列中的資料。
>>> l = [1, 2.0, '3', 4, 5.0]
>>> l.reverse()
>>> l
[5.0, 4, '3', 2.0, 1]
>>> l[::-1]
[5.0, 4, '3', 2.0, 1]
牛刀小試
- b923: stack 堆疊的模板題 [參考答案] ★★
- 使用 for 迴圈、串列、If-Else
- 程式設計步驟:
# 步驟1: 處理資料輸入。
s = input("")
s = s.strip(" \t\r\n")
# 步驟2: 資料類型轉換。
n = int(s)
# 步驟3: 定義一個空串列。
stack = []
# 步驟4: 使用 for 迴圈。
for i in range(0, n):
# 步驟5:處理資料輸入。
s = input("")
s = s.strip(" \t\r\n")
# 步驟6: 取得操作字串。
op = s[0]
# 步驟7: 使用 if 結構判斷操作字串。
if op == "1":
# 刪除stack中索引值top的資料。
top = len(stack) - 1
del stack[top]
elif op == "2":
# 顯示stack中索引值top的資料。
top = len(stack) - 1
print(stack[top])
else:
# 將資料加入stack中。
op, num = s.split()
stack.append(int(num))
牛刀小試2
- a349: 2. 指令解譯器 [參考答案] ★★★★
- 使用 for 迴圈、串列、If-Elif-Else
- 程式設計步驟:
# 步驟1: 定義M, R串列。
M = [0] * 8
R = [0] * 4
# 步驟2: 使用 for 迴圈。
for i in range(0, 8):
# 步驟3: 處理資料輸入。
s = input("")
s = s.strip(" \t\r\n")
# 步驟4: 資料類型轉換及存入串列M中。
M[i] = int(s)
# 步驟5: 處理資料輸入。
n = input("")
n = n.strip(" \t\r\n")
# 步驟6: 資料類型轉換。
n = int(n)
# 步驟7: 建立串列ops。
ops = []
# 步驟8: 使用 for 迴圈
for i in range(0, n):
# 步驟9: 處理資料輸入。
s = input("")
s = s.strip(" \t\r\n")
s = s.split()
# 步驟10: 就資料存入串列ops。
ops.append(s)
# 步驟11: 使用 for 迴圈。
for op in ops:
# 步驟12: 使用 if 結構判斷操作類型。
if op[0] == "LOAD":
# 將串列M中的資料存入串列R。
d = int(op[1])
s = int(op[2])
R[d] = M[s]
elif op[0] == "STORE":
# 將串列R中的資料存入串列M。
d = int(op[1])
s = int(op[2])
M[d] = R[s]
elif op[0] == "ADD":
# 對串列R中的資料做加法及回存至串列R中。
d = int(op[1])
s1 = int(op[2])
s2 = int(op[3])
R[d] = R[s1] + R[s2]
else:
# 將串列R中的資料移到串列R中的其他位置。
d = int(op[1])
s = int(op[2])
R[d] = R[s]
# 步驟13: 顯示輸出結果。
print(R[0])
print(M[0])
躍躍欲試
- for 迴圈 + 串列:
- a009: 解碼器 [參考答案] ★★
- a015: 矩陣的翻轉 [參考答案] ★★
- a034: 二進位制轉換 [參考答案] ★, practice
- a065: 提款卡密碼 [參考答案] ★
- a147: Print it all [參考答案], practice
- a248: 新手訓練 ~ 陣列應用 [參考答案] ★, practice
- d985: Gran Turismo 5 [參考答案] ★
- for 迴圈 + 串列 + If-Else:
- a622: 2. Vertical Printing [參考答案] ★
- b367: 翻轉世界 [參考答案] ★★
- d574: 節約符咒 [參考答案] ★★, practice+
- for 迴圈 + 串列 + If-Elif-Else:
- d139: Compressed String [參考答案] ★★, practice+
- d430: 第二題: 計算字數 (count) [參考答案] ★
- d681: BinaryCount [參考答案] ★
- while 迴圈 + 串列 + If-Elif-Else:
參考資料
- Python自動化的樂趣, 第四章, Al Sweigart 著、H&C 譯, 碁峰
- Python編程入門第3版(簡), 第七章, Toby Donaldson著, 人民郵電出版社
- 精通Python, 第三章, Bill Lubanovic著, 賴屹民譯, 歐萊禮