python中的列表和元組區別分析

列表(list)和元組(tuple)的一些基礎

list和tuple都是一個可以放置任意數據類型的有序集合,都是既可以存放數字、字符串、對象等

file

list和tuple都支持負索引

In [8]: nums[-2]
Out[8]: 'ad'
In [9]: tp[-2]
Out[9]: '33'

list和tuple都支持切片操作

In [10]: nums[1:3]
Out[10]: [3, 'ad']
In [11]: tp[1:3]
Out[11]: (3, '33')

list和tuple都可以隨意嵌套

In [12]: nums = [[1,2,3],[‘s’,’ff’],[’34’,3,5]]
In [13]: tp = ((23,4,’f’),45,’d’,(‘dd’,4,’ff’))

list和tuple的一些區別

  • 列表是動態的,長度大小不固定,可以隨意的增加、刪除、修改元素
  • 元組是靜態的,長度在初始化的時候就已經確定不能更改,更無法增加、刪除、修改元素

file

從圖中看出我們對list做出修改是成功的,但是對tuple修改的時候,確拋出瞭錯誤,那如果想對tuple做出改變該如何做呢?隻能重新開辟一塊內存,重新生成新到的tuple瞭。

file

從tuple的源碼中也可以看出,隻有兩個自帶的方法,一個是統計元素出現的次數一個是查詢元素的索引。

list和tuple存儲方式的差異

我們先來看個例子

In [19]: nums=['a',1,2]
In [20]: tp=('a',1,2)
In [21]: nums.__sizeof__()
Out[21]: 64
In [22]: tp.__sizeof__()
Out[22]: 48

這裡構造瞭一個list和一個tuple。他們存儲的內容是相同的,__sizeof__方法可以打印系統分配空間的大小。可以看到他們所占用的內存空間是不同的,存儲的內容相同,但是list比tuple多占用瞭16自己的內存。

先來看一下一個數組的內存分配過程:

In [23]: l=[]

In [24]: l.__sizeof__() // 空列表分配瞭40字節的內存
Out[24]: 40

In [25]: l.append('a') // 增加瞭一個一個元素後,給列表分配瞭72字節的內存,一個字符8個字節
												// 那就是一次性分配瞭4個字符的內存空間

In [26]: l.__sizeof__()
Out[26]: 72

In [27]: l.append('b') // 再增加字符,占用內存不變

In [28]: l.__sizeof__()
Out[28]: 72

In [29]: l.append('c') // 再增加字符,占用內存不變

In [30]: l.__sizeof__()
Out[30]: 72

In [31]: l.append('d') // 再增加字符,占用內存不變

In [32]: l.__sizeof__()
Out[32]: 72

In [33]: l.append('e') // 再添加元素,內存不夠,觸發重新的內存分配

In [34]: l.__sizeof__()
Out[34]: 104

可以看出list為瞭能夠實時追蹤內存的使用情況,當空間不足時以及分配額外空間,額外的多分配瞭內存,而且還需要存儲指針,指向對應的元素。

我們可以看到,為瞭減小每次增加 / 刪減操作時空間分配的開銷,Python 每次分配空間時都會額外多分配一些,這樣的機制(over-allocating)保證瞭其操作的高效性:增加 / 刪除的時間復雜度均為 O(1)。但是對於元組,情況就不同瞭。元組長度大小固定,元素不可變,所以存儲空間固定。

所以說在存儲大量的數據的時候,這種差異是需要考慮的,如果數據發生變更的可能性不大,就用元組存儲,如果數據是需要頻繁的進行數據的修改增加,就使用列表

推薦閱讀: