Python元組與列表


列表和元組基礎

列表和元組都是一個可以放置任意數據類型的有序集合

# 可以包含所有的數據類型
lst = ['hello', 123, [1,2], {1:2}] tup = ('hello', 123, [1,2], {1:2})

 

列表是動態的, 長度大小不固定, 可以隨意的增加、刪除或者該表元素(mutable)

元組是靜態的, 長度大小固定, 無法增加刪減或者改變(immutable)

lst = ['hello', 123, [1,2], {1:2}]
tup = ('hello', 123, [1,2], {1:2})
# 可以正常的修改數據
lst[
1] = 456 print(lst) ['hello', 456, [1, 2], {1: 2}]
# 元組是不可變的, 做修改的話會報錯
# 如果想對已有的元組做任何'改變', 那就只能重新開辟一塊內存,創建新元組 tup[
1] = 456 print(tup) Traceback (most recent call last): File "E:/Python/review/list_and_tuple.py", line 7, in <module> dup[1] = 456 TypeError: 'tuple' object does not support item assignment

 

lst = ['hello', 123, [1,2], {1:2}]
tup = ('hello', 123, [1,2], {1:2})
# 列表只是添加到原列表末尾
print(id(lst)) # 23153240 lst.append(
'456') print(id(lst)) # 23153240 # 元組做修改會重新開辟一塊空間, 實際上就是創建一個新元組
print(id(tup)) # 52580096 tup
= tup + ('456',) print(id(tup)) # 52579232

 

元組和列表都支持索引和負索引

lst = ['hello', 123, [1,2], {1:2}]
tup = ('hello', 123, [1,2], {1:2})
print(lst[2])  # [1, 2]
print(tup[2])  # [1, 2]
print(lst[-1])  # {1: 2}
print(tup[-1])  # {1: 2}

 

元組和列表都支持切片操作,[開始索引, 結束索引, 步長]  步長為負反轉

lst = ['hello', 123, [1,2], {1:2}]
tup = ('hello', 123, [1,2], {1:2})
print(lst[1:3])  # [123, [1, 2]]
print(tup[1:3])  # (123, [1, 2])
print(lst[::-2])  # [{1: 2}, [1, 2], 123, 'hello']
print(tup[::-1])  # ({1: 2}, 123)

 

列表和元組可以互相轉換

lst = ['hello', 123, [1,2], {1:2}]
tup = ('hello', 123, [1,2], {1:2})
print(tuple(lst))  # ('hello', 123, [1, 2], {1: 2})
print(list(tup))  # ['hello', 123, [1, 2], {1: 2}]

 

列表和元組存儲方式的差異

列表是動態的, 所以需要存儲指針, 來指向對應的元素, 由於列表是可變的, 所以需要額外存儲已經分配的長度大小, 這樣才可以實時追蹤列表空間的使用情況, 當空間不足時, 及時分配額外空間

lst = []
tup = ()
print(lst.__sizeof__())  # 20
print(tup.__sizeof__())  # 12
lst.append(1)
tup = tup + (1,)
print(lst.__sizeof__())  # 36  當空間不足, 列表為其分配了4個元素的空間
print(tup.__sizeof__())  # 16  每次增加4個字節
lst.append(2)
tup = tup + (2,)
print(lst.__sizeof__())  # 36  之前分配了空間, 所以列表空間不變
print(tup.__sizeof__())  # 20  同上
lst.append(3)
tup = tup + (3,)
print(lst.__sizeof__())  # 36  同上
print(tup.__sizeof__())  # 24  同上
lst.append(4)
tup = tup + (4,)
print(lst.__sizeof__())  # 36  同上
print(tup.__sizeof__())  # 28  同上
lst.append(5)
tup = tup + (5,)
print(lst.__sizeof__())  # 52 空間再次不足, 列表再次為其分配了4個元素的空間
print(tup.__sizeof__())  # 32 同上

列表: Python每次分配空間是都會額外多分配一些, 這樣的機制保證了其操作的高效性: 增加/刪除的時間復雜度均為O(1)

元組: 長度大小固定, 元素不可變, 所以存儲空間不變

在數據較小的時候, 差異可以忽略不計, 但是如果數據是上億以上, 那么就不能忽略了

 

列表和元組的性能

元組要比列表更加輕量級一些, 所以總體來說, 元組的性能速度要略優於列表

Python會在后台, 對靜態數據做一些資源緩存, 通常來說因為垃圾回收機制的存在, 如果一些變量不被使用了, Python就會回收它們所占用的內存, 返還給操作系統, 以便其他變量或其他應用使用

但是對於一些靜態變量, 比如元組, 如果他不被使用並且空間不大時, Python會暫時緩存這部分內存, 這樣, 下次我們在創建同樣大小的元組是, Python就可以不用再想操作系統發出請求, 去尋找內存, 而是可以直接分配緩存的內存空間, 這樣就能大大加快程序的運行速度

python3 -m timeit (1,2,3,4,5,6)
20000000 loops, best of 5: 11.9 nsec per loop

python3 -m timeit [1,2,3,4,5,6]
5000000 loops, best of 5: 86 nsec per loop

但如果索引操作的話, 兩者的速度差別非常小, 幾乎可以忽略不計

如果想要增加、刪減或者改變元素, 那么列表顯然更優, 因為元組必須通過新建一個元組來完成

 

列表和元組的使用場景

如果存儲的數據和數量不變, 比如你有一個函數, 需要返回的是一個地點的經緯度, 然后直接傳給前端渲染, 那么肯定選用元組更合適

如果存儲的數據或數量是可變的, 比如社交平台上的一個日志功能, 是統計一個用戶在一周之內看了哪些用戶的帖子, 那么則用列表更合適

 

列表內置函數

長度len

len(list)  返回列表的長度

 

in 與 not in

in 判斷元素是否在列表中

not in 判斷元素是否不在列表中

 

循環 for

for i in list: print(i)

 

追加 append

list.append(n)   在列表的最后追加n

 

按索引添加 insert

list.insert(n,m)   在第n個元素的位置添加m

 

追加一個列表 extend

list.extend([1,2,3])  在列表的末尾一次型追加立一個序列(原組和列表)中的多個值(用新列表擴展原來的列表)

 

按索引刪除 del

del list[n]   n為列表的索引

 

按元素刪除 remove

list.remove(n)   n為列表的元素

 

隨機移除 pop

list.pop(1)  移除列表中的某個元素,並返回該院屬的值

 

最大值 max

max(list)  返回列表中的最大值

 

最小值 min

min(list)   返回列表中的最小值

 

統計次數 count

list.count(n)   n為列表中的元素

 

排序 sort

list.sort()   對列表按照大小排序   reverse=True  參數 反向排序

反轉 reverse

list.reverse()

 

元組內置函數

長度len

len(tuple)  返回元組的長度

 

in 與 not in

in 判斷元素是否在元組中

not in 判斷元素是否不在元組中

 

循環 for

for i in tuple: print(i)

 

最大值 max

max(tuple)

 

最小值 min

min(tuple)

 

總結

總的來說, 列表和元組都是有序的, 可以存儲任意數據類型的集合, 區別主要在於下面的兩點

1. 列表是動態的, 長度可變, 可以隨意的增加、刪減或改變元素, 列表的存儲空間略大於元組, 性能略差與元組

2. 元組是靜態的, 長度大小固定, 不可以對元素進行增加、刪減或改變操作, 元組相對於列表更加輕量級, 性能稍優

 

參考來源

https://time.geekbang.org/column/intro/176


免責聲明!

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



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