Python元組是什么


 

引出

在使用Python過程中,列表、集合和字典是比較常用的數據結構。

  • 列表簡單說就是數組,不對,它就是數組

  • 集合就是去重的元素結構,和JAVA中的set一樣

  • 字典就是一個key-value的鍵值對,和JAVA中的HashTable一樣

但是,Python中有一個特立獨行的對象,元組tuple,看一個元組的簡單使用:

tu = (2, 3)
a = tu[0] # a=2
b = tu[1] # b=3

什么?你告訴我這個一個新的結構?不是數組???

這用起來跟數組也沒什么區別啊?

要看元組和數組的區別,最直觀的比較,就是比較兩個結構的方法,通過方法來理解結果。

方法比較

列表用的比較多了,方法基本上都是常規的數組操作:對數組的增刪改查。對了,還有Python列表最屌的操作,數組的切片操作。

(悄悄告訴你,查看方法只要Python運行 help(list), 就可以了)

再看一下元組的方法,暴露出來的方法只有兩個,countindex

  • count(x): 統計x在元組中的個數

  • index(x): 返回x在元組中第一次出現的索引

恩,我知道區別了,元組只能查,不能做增刪改的操作。

只能查詢,不可修改,這不是常量么。。。。既然是常量,想必虛擬機內部會做優化,元組占用的空間會比列表少很多吧。

內存比較

分別定義列表和元組,查看其內存占用情況:

from sys import getsizeof
​
if __name__ == '__main__':
    tu = (x for x in range(20000))
    li = [x for x in range(20000)]
    print(getsizeof(tu))
    print(getsizeof(li))

輸出結果:

啥?元組這么小么?我兩萬個數字才占用88個字節?我不服,再怎么優化這也不可能,它不是元組:

if __name__ == '__main__':
    tu = (x for x in range(20000))
    li = [x for x in range(20000)]
    print(type(tu))
    print(type(li))

哦哦,不好意思啊,走錯片場了,這是個生成器。重新來過:

from sys import getsizeof
if __name__ == '__main__':
    tu = tuple(x for x in range(20000))
    li = list(x for x in range(20000))
    print(type(tu))
    print(getsizeof(tu))
    print(type(li))
    print(getsizeof(li))
 

這回沒毛病了,元組確實比列表占用空間要少一些。

至此,基本已經確定了,元組最大的特性就是不可變。

通過元組的不可變特性,引申出了很多數組無法實現的功能

這里,看到網上有人說元組中的數組是可變的,也給出了對應的解釋。簡單說,元組中保存的是數組的地址,盡管數組內容變了,但地址沒有變,也就是元組內容沒有發生變化,很好理解。

元組的靈活使用

  1. 元組是可以計算hash值的,這也就意味元組可以當做hashTable中的key存在

if __name__ == '__main__':
    tu = tuple(x for x in range(20000))
    li = list(x for x in range(20000))
    print(hash(tu))
    print(hash(li))

有人說,字符串就足夠了,沒必要用元組。恩?我想到一個應用場景:

如果要通過用戶的信息(身高,體重,性別)來查找用戶的id,我們固然可以遍歷一遍用戶,將符合條件的篩選出來。但這樣太慢了,如果我們維護一個用戶信息為key,值為id數組的hashMap,那查找就十份快速了。

當然,使用字符串也完全可以滿足,將用戶的各種信息拼接起來,但使用元組顯然更加直觀,key直接就是(身高,體重,性別)。

  1. 這個雖然和元組的不可變沒什么關聯,但同樣十分實用。實現函數返回多個值。

def test_fun():
    return 2, 3if __name__ == '__main__':
    a, b = test_fun()
    # 用*來接受剩余的內容
    d, *other = test_fun()
    re = test_fun()
    print(a, b)
    print(re)
    print(type(re))

媽媽再也不用擔心我的函數返回了。

站在巨人的肩膀上

通過先人的成果來理解列表和元組,下面以numpy為例,通過作者對二者的理解來幫助我理解。

import numpy
​
if __name__ == '__main__':
    # 創建一個二維數組
    a = numpy.arange(9).reshape(3, 3)
    print(a)
    tu = (1, 2)
    li = [1, 2]
    print(a[tu])
    print(a[li])

顯然,使用元組訪問時,它接收到的意圖是:我想要下標為1的數組中下標為2的元素。而使用數組訪問時,它收到的意圖是:請把下標為1和下標為2的元素給我。在此,意會一下。

 

 

 

 


免責聲明!

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



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