part3-1 Python列表和元組(列表和元組常用方法使用,序列封包和解包)



Python中內置的三種常用數據結構:列表(list)、元組(tuple)和字典(dict)。這三種數據結構可用於保存多個數據項,可以保存大量數據。列表和元組是按順序存放元素,每個元素有自己的索引,可通過索引訪問元素,兩者的區別在於,元組是不可修改的,列表可以修改。字典以 key-value(鍵值對)形式保存數據。這三種數據結構是編程中必不可少的內容。

一、序列介紹

序列是指一種包含多項數據的數據結構,序列包含的多個數據項(也叫成員)按順序排列,可通過索引來訪問成員。

常見的序列類型有:字符串、列表、元組。字符串和元組序列類型是不可變的,一旦創建就不能修改其所包含的成員。列表是可變序列,程序可以修改列表序列中的元素。在實際運用時,如果保存固定個數的數據項,而不需要修改時,就應該使用元組。

列表創建:使用方括號,元素之間用英文逗號分隔。也可將可迭代對象傳遞給內置函數list()來創建。
元組創建:使用圓括號,元素之間用英文逗號分隔。也可將可迭代對象傳遞給內置函數tuple()來創建。

二、 列表和元組的通用方法

只要不涉及到改變元素的操作,列表和元組的用法是通用的。

1、 通過索引使用元素

列表和元組的索引都是從0開始,第1個元素的索引為0,第2個元素的索引為1,......,以此類推;還可以使用負數索引,倒數第1個元素的索引為-1,倒數第2個元素的索引為-2,......,以此類推。

列表的元素相當於一個變量,程序可使用它的值,也可對元素賦值;元組的元素相當於一個常量,程序只能使用它的值,不能重新賦值。
示例如下:
name = ('python', 'c', 'java', 'go', 'linux') # 定義一個元組
print(name) # 輸出整個元組
print(name[0]) # 訪問元組第1個元素
print(name[1]) # 訪問元組第2個元素
print(name[-1]) # 訪問元組倒數第1個元素
print(name[-2]) # 訪問元組倒數第2個元素

上面通過索引訪問元組的方法同樣適用於列表。

2、 子序列

字符串可通過切片獲取一個子串,列表和元組同樣也可使用索引獲取中間一段,該方法中叫作slice(分片或切片),語法格式如下:
[start: end: step]
start和end兩個索引可以使用正數或負數,負數表示從倒數開始。語法表示從start索引開始(包含),到end索引結束(不包含)。
step表示步長,也可使用負數。示例如下:
name = ['python', 'c', 'java', 'go', 'linux'] # 定義一個列表
print(name[2:4]) # 訪問第3個到第5個(不包含)索引間的元素,輸出:['java', 'go']
print(name[-3:-1]) # 訪問倒數第3個到倒數第1個間的元素,輸出:['java', 'go']
print(name[1:-2]) # 訪問從第2個到倒數第2個間的元素,輸出:['c', 'java']
print(name[1:4:2]) # 訪問從第2個到第5個(不包含)、間隔為2的元素,輸出:['c', 'go']
print(name[::-1]) # 反轉列表

上面對列表進行切片的操作,同樣適用於元組。

3、 列表和元組的加法運算

列表和列表相加,元組和元組相加,不能直接將列表和元組相加。
a_tuple = (1, 2)
b_tuple = (3, 4)
sum_tuple = a_tuple + b_tuple # 兩個元組相加后,a_tuple和b_tuple並沒有任何改變
print(sum_tuple) # 輸出:(1, 2, 3, 4)
# a_tuple + [10, 20] # 元組和列表相加,報 TypeError 錯誤。
print([10, 20] + ['a', 'b']) # 計算兩個列表相加,輸出:[10, 20, 'a', 'b']

4、 列表和元組的乘法運算

列表和元組可以和整數N相乘,得到的結果是列表和元組的元素重復N次。示例如下:
print([1, 'a'] * 3) # 輸出:[1, 'a', 1, 'a', 1, 'a']
print(('a', 'z') * 3) # 輸出:('a', 'z', 'a', 'z', 'a', 'z')

列表和元組可以同時使用加法、乘法。一個簡單示例如下:
# 創建一個表示一個月31天中的后綴字符元組,對於1、2、3是st、nd、rd,其他使用 th 代表。
order_endings = ('st', 'nd', 'rd') + \
('th',) * 17 + ('st', 'nd', 'rd') \
+ ('th',) * 7 + ('st',)
print(order_endings)
day = input("輸入日期(1-31):")
day_int = int(day)
print(day + order_endings[day_int - 1])

在這個示例中 order_endings 得到一個合並后的元組,要注意 ('th',) 的寫法,當元組只有一個元素時,要在這個唯一的元素后面加英文逗號,不加英文逗號就表示的是字符串,字符串和元組不能相加。運行示例如下:
輸入日期(1-31):28
28th

5、in 運算符
in 運算符用於判斷列表或元組是否包含某個元素,判斷結果是 bool 型值。示例如下:
a_tuple = ('python', 'java', 'c++')
print('java' in a_tuple) # 輸出:True
print('go' in a_tuple) # 輸出:False

6、 長度、最大值和最小值

Python內置的len()、max()、min() 全局函數可用於獲取列表或元組的長度、最大值和最小值。其中 max()、min() 要對元組、列表中的元素比較大小,因此傳給 max()、min()函數的元組、列表的元素必須是相同類型並且可以比較大小。示例如下:
a_tuple = (100, 33, 88, 50, 106) # 數字類型元組,每個元素類型相同
print(len(a_tuple)) # 計算長度,輸出:5
print(max(a_tuple)) # 計算最大值,輸出:106
print(min(a_tuple)) # 計算最小值,輸出:33

b_list = ['Python', 'Java', 'Linux', '世界'] # 字符串類型的列表,每個元素類型相同
print(len(b_list)) # 計算長度,輸出:4
print(max(b_list)) # 計算最大值,輸出:世界
print(min(b_list)) # 計算最小值,輸出:Java

由上面示例可知,Python中字符串是可以比較大小的,按照字符串中每個字符對應的編碼來比較字符串的大小。

7、 序列封包和序列解包

序列封包(Sequence Packing)和序列解包(Sequence Unpacking)功能,可支持下面兩種賦值方式。
(1)、程序把多個值賦給一個變量時,Python會自動將多個值封裝成元組。這種功能叫做序列封包。
(2)、程序允許將序列(字符串、元組、列表等)直接賦值給多個變量,此時序列的各元素會被依次賦值給每個變量(要求序列的元素個數和變量個數相等)。這種功能叫做序列解包。

示例如下:
res = 1, 2, 3 # 序列封包,封包成一個元組賦值給 res 變量
print(res) # 輸出是序列:(1, 2, 3)
print(type(res)) # 查看類型是元組類型,輸出:<class 'tuple'>
x, y, z = res # 序列解包,序列中的元素依次賦值給 x、y、z三個變量

在賦值時同時使用了序列封包和序列解包機制,可讓賦值運算符同時將多個值賦給多個變量,例如:
x, y, z = 10, 20, 30
上面這行代碼實際執行過程是:
(1)、先執行序列封包
xyz = 10, 20, 30
(2)、再執行序列解包
x, y, z = xyz
使用這種語法可實現交換變量的值,例如:
x, y, z = y, z, x

序列解包時,也可只解出部分,就是剩下的依然使用列表變量保存。使用這種方式解包時,可以在左邊被賦值的變量之前添加“*”,這個變量就代表一個列表,可以保存多個集合元素。示例如下:
first, second, *rest = range(10)
print(first) # 輸出:0
print(second) # 輸出:1
print(rest) # 輸出:[2, 3, 4, 5, 6, 7, 8, 9]

*_, last = range(10) # 解包時保存最后一個元素,其它元素丟棄
first, *middle, last = range(10) # 保存第一個和最后一個元素,中間元素統一保存到列表中

三、 使用列表

元組不可變,列表是可變的。元組支持的操作,列表基本上都支持;列表支持對元素的修改,而元組不支持。如果程序不修改元素,可使用元組替代列表會更安全。另外,同樣元素的列表和元組,元組占用的內存空間要小一些。

1、 創建列表

創建列表可用方括號,也可用內置的 list() 函數來創建,list() 函數可用於將元組、區間(range)等對象轉換為列表。示例如下:
a_tuple = ('python', 'java', 'go') # 創建元組
a_list = list(a_tuple) # 使用 list() 函數將元組轉列表
print(a_list) # 輸出是列表:['python', 'java', 'go']
print(range(5)) # 區間是一個可迭代對象,輸出:range(0, 5)
print(list(range(5))) # 使用 list() 函數將區間轉換為列表,輸出:[0, 1, 2, 3, 4]

區間函數 range() 有3個參數,分別是 start, stop, step。省略 start 參數時,默認從0開始,stop 參數是區間的結尾,不能省略,在計算區間時不包含結尾。step 參數是步長,省略時默認為1,該參數可以是負數。在Python2中的 xrange() 函數與Python3版本中的 range() 相同,在Python2中的 range() 函數返回的是列表。

創建元組也有相應的內置函數 tuple(),該函數可用於將列表、區間(range)等對象轉換為元組。示例如下:
a_list = ['python', 'java', 'go']
a_tuple = tuple(a_list) # 使用 tuple() 函數將列表轉換為元組
b_tuple = tuple(range(10, 1, -2)) # 將區間對象轉換為元組

2、 增加列表元素,append()、extend()、insert() 方法

列表的 append() 方法可把傳入的參數追加到列表的最后面。append() 方法可接收單個值參數,也可接收元組、列表等參數,但是接收的元組、列表會當成單個元素,這樣會形成在列表中嵌套列表、嵌套元組的情形。示例如下:
a_list = [1, '2', 3]
a_list.append('a') # 在列表中追加元素
print(a_list) # 輸出是:[1, '2', 3, 'a']
a_list.append((4, '5')) # 追加一個元組,元組被當成一個元素
print(a_list) # 輸出是:[1, '2', 3, 'a', (4, '5')]
a_list.append([6, '7']) # 追加列表,列表被當成一個元素
print(a_list) # 輸出是:[1, '2', 3, 'a', (4, '5'), [6, '7']]

如果不希望列表、元組當成整體被追加到列表中,只是追加列表中的所有元素,則可使用 extend() 方法。示例如下:
b_list = [1, '2']
b_list.extend((3, '4')) # 參數是元組,但追加的仍是元組中的所有元素
print(b_list) # 輸出是:[1, '2', 3, '4']
b_list.extend([5, '6']) # 追加列表中的所有元素
print(b_list) # 輸出是:[1, '2', 3, '4', 5, '6']
b_list.extend(range(8, 10)) # 還可以追加區間中的所有元素
print(b_list) # 輸出是:[1, '2', 3, '4', 5, '6', 8, 9]

在列表的指定位置插入元素,可使用 insert() 方法,示例如下:
c_list = [1, 2, 3, 4]
c_list.insert(2, 'p') # 在索引2處插入字符串
print(c_list) # 輸出是:[1, 2, 'p', 3, 4]
c_list.insert(2, tuple('py')) # 在索引2處插入一個元組,元組被當成一個元素
print(c_list) # 輸出是:[1, 2, ('p', 'y'), 'p', 3, 4]

3、 刪除列表元素,del、remove()方法、clear()方法

del 語句是Python的一種語句,專用於刪除操作,不僅可用於刪除列表的元素,還可用於刪除變量等。

del 語句可刪除列表中的單個元素,也可直接刪除列表的中間一段,示例如下:
a_list = [1, 'a', 2, 'b']
del a_list[2] # 刪除列表第3個元素
print(a_list) # 輸出是:[1, 'a', 'b']
del a_list[1:3] # 通過列表切片,可一次性刪除多個元素,切片還可以設定步長

del 語句還可刪除普通變量,示例如下:
name = 'michael'
del name # 刪除name 變量
print(name) # 報錯:NameError

remove() 方法刪除列表元素時,不根據索引來刪除元素,而是根據元素本身來刪除。只刪除在列表中第一個找到的元素。如果在列表中未找到要刪除的元素,則報ValueError錯誤。示例如下:
c_list = [10, 'python', 20, 'java', 20, 'go', 'python']
c_list.remove(20) # 刪除第一次找到的元素
print(c_list) # 輸出:[10, 'python', 'java', 20, 'go', 'python']

clear() 方法表示清空列表的所有元素。示例如下:
c_list.clear()
print(c_list) # 輸出空列表:[]

4、 修改列表元素

列表的元素可看做是變量,程序可對列表的元素賦值,這樣就達到修改列表元素。通過索引對列表元素賦值,索引可以是正數索引,也可以是負數索引。還可以通過切片語法對列表中某一部分賦值,使用切片操作時,新賦值的元素個數可以不等於原來的元素個數。這相當於在給列表增加或刪除元素。示例如下:
d_list = list(range(1,5))
d_list[2] = 30 # 修改列表單個元素的值,結果:[1, 2, 30, 4]
d_list[1] = [10, 20] # 修改列表,結果:[1, [10, 20], 30, 4]
d_list[-1] = 40 # 修改列表最后一個元素的值,結果:[1, [10, 20], 30, 40]
d_list[1:3] = ('a', 'b', 'c') # 通過切片索引修改,切片末尾不包含,結果:[1, 'a', 'b', 'c', 40]

列表的切片索引中的起始索引和結束索引相等時,切片的結果是空列表,利用這個特性,可為列表插入元素。
d_list[2:2] = ['x', 'y'] # 切片起始索引等於結束索引,結果是在列表中指定位置插入元素
print(d_list) # 輸出是:[1, 'a', 'x', 'y', 'b', 'c', 40]

如果將列表中某一段賦值為空列表,就變成從列表中刪除元素。
d_list[2:5] = [] # 結果是2、3、4的元素被刪除:[1, 'a', 'c', 40]

當對切片賦值單個值時,如果這個值是字符串,Python會把這個字符串當成序列處理,字符串的每個字符都是一個元素。如下示例:
d_list[1:3] = 'python' # 對切片賦值字符串,結果:[1, 'p', 'y', 't', 'h', 'o', 'n', 40]
d_list[1:3] = 100 # 對切片賦值一個數字常量,會報錯:TypeError

使用切片賦值時,還可指定 step 參數,如果指定 step 參數,則要求所賦值的列表元素個數與所替換的列表個數相等。如下所示:
d_list[1: 6: 2] = [10, 20, 30]
print(d_list) # 輸出是:[1, 10, 'y', 20, 'h', 30, 'n', 40]

5、 列表的其他常用方法

列表的方法中還有很多以雙下划線開頭的方法,這些方法有特殊意義,不建議使用。除這些雙下划線方法外,列表可用的方法可在命令行使用 dir(list) 查看。
dir(list) # 剔除雙下划線方法后,輸出如下:
['append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

這些方法中還有一些前面未說過的,同樣是常用的方法:
(1)、count()方法:統計列表中某個元素出現的次數。
(2)、index()方法:判斷某個元素在列表中出現的位置,如果該元素不在列表中,報 ValueError 錯誤。
(3)、pop()方法:將列表中最后一個元素取出,相當於出棧。默認取出列表最后一個元素。
(4)、reverse()方法:反轉列表,將列表中的元素反向存放。
(5)、sort()方法:用於對列表元素排序。

(1)、 count()方法使用
a_list = [10, 20, [10, 20], 20, 30]
print(a_list.count(20)) # 統計20在列表中出現的次數,不統計在嵌套列表中出現的次數,輸出:2
print(a_list.count([10, 20])) # 輸出:1

(2)、index() 方法使用
index()方法查找某個元素在列表中的出現的位置,如果該元素沒有出現,則報 ValueError錯誤。該方法還可以傳入 start、end 參數,用於在列表指定的范圍內搜索元素。示例如下:
print(a_list.index(20)) # 查找元素 20 第一次出現的位置,輸出:1
print(a_list.index(20, 2)) # 從索引2開始,查找元素 20 第一次出現的位置。
print(a_list.index(10, 1, 4)) # 在索引1到索引4之間找元素 10第一次出現的位置,找不到,報:ValueError

(3)、 pop() 方法使用

列表的 pop() 方法可實現元素出棧功能。棧是一種特殊數據結構,可實現先進后出(FILO,First in Last out)和 先進先出(FIFO,First in First out)功能。在其他編程語言中,有一個入棧方法 push(),在Python中可使用 append 代替 push() 方法。

pop()方法從列表取出元素后,會返回取出的元素,並且列表中相應的元素被移除。示例如下:
stack = ['a', 'b']
stack.append('c') # 入棧一個元素
print(stack.pop()) # 出棧一個元素,默認取出列表最后一個元素,輸出:c
print(stack) # 此時的列表已經沒有 c 這個元素,輸出:['a', 'b']
print(stack.pop(0)) # 傳遞索引給 pop() 方法,取出指定的元素,輸出:a

(4)、 reverse()方法使用
reverse()方法反轉列表中的所有元素順序,該方法會對列表進行就地修改。示例如下:
a_list = list(range(5))
a_list.reverse() # 反轉列表中的元素順序
print(a_list) # 輸出:[4, 3, 2, 1, 0]
a_list[::-1] # 使用切片索引也能反轉列表,但不會就地修改原列表

(5)、 sort() 方法使用
列表的sort() 方法默認對列表的元素按大小排序,默認是從小到大(升序)排序。傳遞參數 reverse=True 時,表示從大到小排序。還可以傳遞 key 參數改變排序方式,key 參數需要的是一個函數名,排序的方式由這個函數的功能決定。示例如下:
num_list = [5, -2, 7, -9, 11]
num_list.sort() # 默認排序,從小到大
print(num_list) # 輸出:[-9, -2, 5, 7, 11]
num_list.sort(reverse=True) # 傳遞參數 reverse=True 改變默認排序,從大到小排序
str_list = ['pyt', 'go', 'java', '走你,python']
str_list.sort() # 對字符串元素排序,默認按字符串包含的字符的編碼來比較大小
print(str_list) # 輸出:['go', 'java', 'pyt', '走你,python']

str_list.sort(key=len) # 給 key 參數傳遞函數名 len,表示元素長度排序
print(str_list) # 輸出:['go', 'pyt', 'java', '走你,python']
str_list.sort(key=len, reverse=True) # 長度從大到小排序
print(str_list) # 輸出:['走你,python', 'java', 'pyt', 'go']

在Python2中列表的 sort() 方法可傳入一個比較大小的函數,該函數負責比較列表元素的大小。該函數有兩個參數,該函數返回正整數時表示第一個參數大於第二個參數;返回負整數時,表示函數第一個參數小於第二個參數;返回0時,表示兩個參數相等。示例如下:
# 在Python2 中執行
def len_cmp(x, y):
'''定義一個根據長度比較大小的函數'''
return 1 if len(x) > len(y) else (-1 if len(x) < len(y) else 0)
str_list.sort(len_cmp)
print(str_list) # 輸出:['go', 'pyt', 'java', '走你,python']


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM