Python-3-列表和元組

程序是用來處理數據的,那麼有兩個重要的問題,數據從何而來以及如何存儲,這裏主要說的就是後一個問題,數據如何存儲,Python提供了很好的數據存儲類型,列表,元組和字典

列表

列表定義

什麼是列表,列表是由一系列按特定順序排列的元素組成,這裏有兩個關鍵詞,特定順序以及元素。說明列表存儲的數據是有序的,另外也說明了列表存儲的是元素,python中的元素不特指某種類型,元素之間也沒有任何聯繫,也就是說可以存儲各種數據類型。

在Python中,用方括號來表示列表([]),用逗號分割元素。例如

name_list = ['Jack', 'Tom', 'Ben', 'Eva']
print(name_list)

print會將其格式化輸出

['Jack', 'Tom', 'Ben', 'Eva']

列表既然是有序的,那麼我們便可按照順序去取其中的元素,對於需要得到的元素,只需要知道其位置(索引),便可獲取,這裏有點像其他語言的數組,說着說就是其他語言數組的擴展。所以其索引位置是從0開始,而不是從1開始。在大多數編程語言中都是如此,這與列表操作的底層實現相關。
創建一個空列表

name_list = []
print(name_list) # 輸出:[]

創建並初始化列表

name_list = ['Jack', 'Tom', 'Ben', 'Eva']
print(name_list[0]) # 輸出:Jack

列表的增刪改查

python還提供了一個不錯的索引方式,索引位置可以爲複數,代表着倒數第幾個

name_list = ['Jack', 'Tom', 'Ben', 'Eva']
print(name_list[-1]) # 輸出:Eva

這裏擴展一個小知識點,type()可以查看數據類型,例如

>>> type(name_list)
<class 'list'>
>>> type(name_list[0])
<class 'str'>

另外使用列表時候要注意一點,所應位置不能超出範圍,否則會造成越界異常

>>> print(name_list[4])
Traceback (most recent call last):
  File "<pyshell#21>", line 1, in <module>
    print(name_list[4])
IndexError: list index out of range

既然存儲了多個數據,那麼就應該提供增刪改查的方法吧,查在上面已經引出了,那麼其他的添加,修改和刪除呢?
首先是修改,要修改哪個值,首先要知道那個值,比如上面的名字列表,要修改"Tom",那麼先知道其位置1,然後重新賦值,就會修改其值了,由此也可以知道,列表是由鏈表實現的。

name_list = ['Jack', 'Tom', 'Ben', 'Eva']
name_list[1] = "Candy"
print(name_list) # 輸出:['Jack', 'Candy', 'Ben', 'Eva']

那麼在列表中要如何添加元素呢?列表本身提供了很多方法去添加元素
在末尾添加

name_list = ['Jack', 'Candy', 'Ben', 'Eva']
print(name_list) # 輸出:['Jack', 'Candy', 'Ben', 'Eva']
name_list.append('Tom')
print(name_list) # 輸出:['Jack', 'Candy', 'Ben', 'Eva', 'Tom']

在任意位置插入元素

name_list = ['Jack', 'Candy', 'Ben', 'Eva']
print(name_list) # 輸出:['Jack', 'Candy', 'Ben', 'Eva']
name_list.insert(1, 'Tom')
print(name_list) # 輸出:['Jack', 'Tom', 'Candy', 'Ben', 'Eva']

最後就只剩下刪除元素了,python中刪除元素,使用del語句

name_list = ['Jack', 'Candy', 'Ben', 'Eva']
print(name_list) # 輸出:['Jack', 'Candy', 'Ben', 'Eva']
del name_list[1]
print(name_list) # 輸出:['Jack', 'Ben', 'Eva']

這個del和其他的列表方法不一樣,那麼和append()insert()相似的方法有麼,答案是肯定的,接下來就來看看刪除方法pop(),知道堆棧概念就很容易知道這個pop的意思了,就是彈出,彈出最後一個元素,並且將其值返回

name_list = ['Jack', 'Candy', 'Ben', 'Eva']
print(name_list) # 輸出:['Jack', 'Candy', 'Ben', 'Eva']
pop_name = name_list.pop()
print(name_list) # 輸出:['Jack', 'Candy', 'Ben']
print(pop_name) # 輸出:Eva

當然,pop也可以彈出指定位置的元素

name_list = ['Jack', 'Candy', 'Ben', 'Eva']
print(name_list) # 輸出:['Jack', 'Candy', 'Ben', 'Eva']
pop_name = name_list.pop(1)
print(name_list) # 輸出:['Jack', 'Ben', 'Eva']
print(pop_name) # 輸出:Candy

另外,還可以根據元素值去刪除元素,使用remove()方法,此時是沒有返回值的,想想這樣的設計還是有道的

name_list = ['Jack', 'Candy', 'Ben', 'Eva']
print(name_list) # 輸出:['Jack', 'Candy', 'Ben', 'Eva']
name_list.remove("Jack")
print(name_list) # 輸出:['Candy', 'Ben', 'Eva']

需要注意的是,pop刪除要注意不要越界,否則會報錯;remove刪除會按順序查找要刪除的值,找到刪除不在查找,另外如果刪除的值找不到,那麼則會報錯

ValueError: list.remove(x): x not in list

列表既然是有序的,那麼也就是可以對其進行按照某種規則規則排序
Python方法sort()能夠爲列表進行排序,而sort(reverse=True)則可以逆序排序,當然這個排序是永久性的

name_list = ['Jack', 'Candy', 'Ben', 'Eva']
print(name_list) # 輸出:['Jack', 'Candy', 'Ben', 'Eva']
name_list.sort()
print(name_list) # 輸出:['Ben', 'Candy', 'Eva', 'Jack']

列表還可以通過reverse()進行反轉,也是永久性的改變原列表

name_list = ['Jack', 'Candy', 'Ben', 'Eva']
print(name_list) # 輸出:['Jack', 'Candy', 'Ben', 'Eva']
name_list.reverse()
print(name_list) # 輸出:['Eva', 'Ben', 'Candy', 'Jack']

要知道列表的長度,可以使用len(list)

name_list = ['Jack', 'Candy', 'Ben', 'Eva']
print(name_list) # 輸出:['Jack', 'Candy', 'Ben', 'Eva']
print(len(name_list)) # 輸出:4

列表的一些方法彙總

append() # 追加
clean() # 清空
copy() # 拷貝
count() # 計算出現次數
extend() # 追加可迭代對象
index() # 查找元素位置
insert() # 插入元素
pop() # 刪除值(右優先),remove(),左優先
reverse() # 反轉
sort() # 排序,升序 sort(reverse=True)降序

列表的遍歷

列表中存在這許多元素,上面談到了列表單個元素的讀取,那麼也可以遍歷整個列表

name_list = ['Jack', 'Candy', 'Ben', 'Eva']
for name in name_list:
	print(name)

這裏涉及到了for循環,屬於流程控制的一種,還應注意到縮進在python中的作用
for循環後面是有一個冒號的,這點要注意
當縮進了不必要的代碼,編譯器會提示

IndentationError: unexpected indent

但在循環中,有時候應該在循環體中執行的代碼放到了外面,這時候編譯器並不會報錯,但會出現預期之外的結果,這種情況就需要仔細排查

數字列表

另外,有時候需要生成數值列表,此時可以使用range()方法生成range
range屬於一個類型

print(type(range(1,5))) # 輸出:<class 'range'>

range也屬於可迭代類型

for value in range(1,5):
	print(value)

以上語句代表生成1~5的數字,包含1不包含5,即[1,5)
即輸出結果爲:1,2,3,4
那麼,可以使用list()將range轉化爲列表

numbers = list(range(1,6))
print(numbers) # 輸出:[1, 2, 3, 4, 5]

range還可指定步長,即從什麼數值開始,到什麼數值,每次增加多少,步長可爲負數,不在範圍輸出空列表

numbers = list(range(2, 11, 2))
print(numbers) # 輸出:[2, 4, 6, 8, 10]
numbers = list(range(11, 2, -2))
print(numbers) # 輸出:[11, 9, 7, 5, 3]
numbers = list(range(2, 11, -2))
print(numbers) # 輸出:[]

數字列表的常用方法

nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
print(min(nums)) # 輸出:0,求最小值
print(max(nums)) # 輸出:9,求最大值
print(sum(nums)) # 輸出:45,求和

列表解析

列表解析將for 循環和創建新元素的代碼合併成一行,並自動附加新元素
例如如下例子

squares = []
for value in range(1, 11):
    squares.append(value ** 2)
print(squares) # 輸出:[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

使用列表解析表達爲

squares = [value ** 2 for value in range(1, 11)]
print(squares) # 輸出:[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

列表切片

既然列表是很多元素組成的,那麼就可以使用其中一部分元素作爲一個新列表進行使用
在python中,這種操作叫做切片,要創建切片,可指定要使用的第一個元素和最後一個元素的索引,同樣的。切片也是從零開始計數的,也支持從後往前的負數形式,不可避免地也存在越界的問題,使用方括號,起點到終點,中間用冒號(:)`隔開,第一個索引省略代表從零開始,第二個索引省略代表一直到結束
例如

name_list = ['Jack', 'Candy', 'Ben', 'Eva']
print(name_list)  # 輸出:['Jack', 'Candy', 'Ben', 'Eva']
print(name_list[0:2])  # 輸出:['Jack', 'Candy']
print(name_list[:3])  # 輸出:['Jack', 'Candy', 'Ben']
print(name_list[0:])  # 輸出:['Jack', 'Candy', 'Ben', 'Eva']
print(name_list[-2:])  # 輸出:['Ben', 'Eva']

切片切出來的任然是一個列表,因此可以做一切列表的操作,這裏注意一點,切片出來的列表存儲在另外的內存區域,下面來做驗證

name_list = ['Jack', 'Candy', 'Ben', 'Eva']
print(id(name_list)) # 輸出:2390115671240
name_list_copy = name_list[:]
print(id(name_list_copy)) # 輸出:2390115271752

由輸出id可知,兩個列表位於不同的內存位置(輸出數字代表內存位置,這個是由操作系統分配的地址),再看下面這個例子:

name_list = ['Jack', 'Candy', 'Ben', 'Eva']
name_list_test = name_list
name_list.append('Tom')
print(name_list)  # 輸出:['Jack', 'Candy', 'Ben', 'Eva', 'Tom']
print(name_list_test)  # 輸出:['Jack', 'Candy', 'Ben', 'Eva', 'Tom']
print(id(name_list))  # 輸出:2823934893256
print(id(name_list_test))  # 輸出:2823934893256

由上可知,當需要拷貝一份另作操作的時候,就需要使用切片和不是賦值,賦值實際上只是內存值的傳遞
這裏涉及到一個概念,深拷貝與淺拷貝,關於這個問題的實質,在之前的C語言中也具體講過,這裏不再羅嗦(其實是因爲解釋起來比較麻煩)

元組

元組實際上就是一種特殊的列表
列表在程序運行期間是可以改變數據集的,而如果這些數據集不可改變,那麼就變成了元組。即Python將不能修改的值稱爲不可變的 ,而不可變的列表被稱爲元組。

元組的定義

與列表不同的是,元組使用圓括號(())來標識。元組的使用也和列表大相徑庭,例如定義一個矩形

dimensions = (100, 50)
print(dimensions[0]) # 輸出:100
print(dimensions[1]) # 輸出:50

當試圖修改元組的值時,Python編譯器會報錯

TypeError: 'tuple' object does not support item assignment

當然,元組也是可以遍歷的

dimensions = (100, 50)
for dimension in dimensions:
    print(dimension)

元組雖然你不可改變元素,但可以重新賦值,這裏的本質實際上就是改變了內存指針的指向,下面做一下驗證

dimensions = (100, 50)
print(id(dimensions)) # 輸出:1777069244744
dimensions = (80, 50)
print(id(dimensions)) # 輸出:1777069206856
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章