關於我
編程界的一名小小程序猿,目前在一個創業團隊任team lead,技術棧涉及Android、Python、Java和Go,這個也是咱們團隊的主要技術棧。 聯繫:hylinux1024@gmail.comhtml
數組類型是各類編程語言中基本的數組結構了,本文來盤點下Python
中各類「數組」類型的實現。python
list
tuple
array.array
str
bytes
bytearray
其實把以上類型都說成是數組是不許確的。這裏把數組看成一個廣義的概念,即把列表、序列、數組都看成array-like
數據類型來理解。linux
注意本文全部代碼都是在Python3.7
中跑的^_^編程
list
應該是Python
最經常使用到的數組類型了。它的特色是可變的、能動態擴容,可存儲Python
中的一切對象,使用時不用指定存儲的元素的類型。小程序
使用很是簡單數組
>>> arr = ["one","two","three"]
>>> arr[0]
'one'
# 動態擴容
>>> arr.append(4)
>>> arr
['one', 'two', 'three', 4]
# 刪除一個元素
>>> del arr[2]
>>> arr
['one', 'two', 4]
複製代碼
tuple
的操做與list
相似。它的特色是不可變,不能擴容,可存儲Python
中的一切對象,使用時不用指定存儲的元素的類型。bash
>>> t = 'one','two',3
>>> t
('one', 'two', 3)
>>> t.append(4)
AttributeError: 'tuple' object has no attribute 'append'
>>> del t[0]
TypeError: 'tuple' object doesn't support item deletion 複製代碼
tuple
可使用+
運算符,這個運算將建立一個新的tuple
對象用於存儲數據。數據結構
>>> t+(1,)
('one', 'two', 3, 1)
>>> tcopy = t+(1,)
>>> tcopy
('one', 'two', 3, 1)
>>> id(tcopy)
4604415336
>>> id(t)
4605245696
複製代碼
能夠看出tuple
執行+
運算符以後兩個對象的地址是不同app
若是在Python
中要用到其它語言中相似「數組」的數據結構,就須要用到array
模塊了。它的特色是可變的、存儲相同類型的數值,不能存儲對象。編程語言
由於array
在使用的時候要指定元素數據類型,所以它比list
和tuple
都有比較高效空間性能。
# 使用時指定元素數據類型爲`float`
>>> arr = array.array('f', (1.0, 1.5, 2.0, 2.5))
>>> arr
array('f', [1.0, 1.5, 2.0, 2.5])
# 修改一個元素
>>> arr[1]=12.45
>>> arr
array('f', [1.0, 12.449999809265137, 2.0, 2.5])
# 刪除一個元素
>>> del arr[2]
>>> arr
array('f', [1.0, 12.449999809265137, 2.5])
# 增長一個元素
>>> arr.append(4.89)
>>> arr
array('f', [1.0, 12.449999809265137, 2.5, 4.889999866485596])
# 若是將一個字符串類型數據存儲到一個浮點數的數組將會報錯
>>> arr[0]='hello'
TypeError: must be real number, not str
複製代碼
array
中元素的數據類型能夠參考下表
Type code | C Type | Python Type |
---|---|---|
'b' | signed char | int |
'B' | unsigned char | int |
'u' | Py_UNICODE | Unicode character |
'h' | signed short | int |
'H' | unsigned short | int |
'i' | signed int | int |
'I' | unsigned int | int |
'l' | signed long | int |
'L' | unsigned long | int |
'q' | signed long long | int |
'Q' | unsigned long long | int |
'f' | float | float |
'd' | double | float |
Python3
中使用str
對象來表示一個文本字符序列(看,這跟Java
中的字符串String
是多麼類似呢)。它的特色不可變的Unicode
字符序列。
在str
中它的每個元素都是字符串對象。
>>> s ='123abc'
>>> s
'123abc'
>>> s[0]
'1'
>>> s[2]
'3'
# 字符串是不可變的序列,不能刪除其中的元素
>>> del s[1]
TypeError: 'str' object doesn't support item deletion # 要對字符串進行操做,能夠轉化成list >>> sn = list(s) >>> sn ['1', '2', '3', 'a', 'b', 'c'] >>> sn.append(9) >>> sn ['1', '2', '3', 'a', 'b', 'c', 9] # 字符串中的元素也是字符串對象 >>> type(s[2]) <class 'str'> >>> type(s) <class 'str'> 複製代碼
str
對象也能夠執行+
操做,它也會生成一個新對象用於存儲。
>>> s2 = s+'33'
>>> s2
'123abc33'
>>> id(s2)
4605193648
>>> id(s)
4552640416
複製代碼
bytes
對象用於存儲字節序列,它的特色是不可變存儲,可存儲0-256的數值。
>>> b = bytes([0,2,4,8])
>>> b[2]
4
>>> b
b'\x00\x02\x04\x08'
>>> b[0]=33
TypeError: 'bytes' object does not support item assignment
>>> del b[0]
TypeError: 'bytes' object doesn't support item deletion 複製代碼
bytearray
對象與bytes
相似,用於存儲字節序列。它的特色是可變的,能動態擴容的字節數組。
>>> ba = bytearray((1,3,5,7,9))
>>> ba
bytearray(b'\x01\x03\x05\x07\t')
>>> ba[1]
3
# 刪除一個元素
>>> del ba[1]
>>> ba
bytearray(b'\x01\x05\x07\t')
>>> ba[0]=2
>>> ba[0]
2
# 添加一個元素
>>> ba.append(6)
# 只能添加字節
>>> ba.append(s)
TypeError: 'str' object cannot be interpreted as an integer
>>> ba
bytearray(b'\x02\x05\x07\t\x06')
# 字節的範圍是0-256
>>> ba[2]=288
ValueError: byte must be in range(0, 256)
複製代碼
bytearray
能夠轉化成bytes
對象,但效率不是很高。
# bytearray轉成bytes將生成一個新對象
>>> bn = bytes(ba)
>>> id(bn)
4604114344
>>> id(ba)
4552473544
複製代碼
tuple->list
>>> tuple(l)
('a', 'b', 'c')
複製代碼
list->tuple
>>> t
('a', 'b', 'c')
>>> list(t)
['a', 'b', 'c']
複製代碼
str->list
>>> l = list('abc')
>>> l
['a', 'b', 'c']
複製代碼
list->str
>>> l
['a', 'b', 'c']
>>> ''.join(l)
'abc'
複製代碼
str->bytes
>>> s = '123'
>>> bytes(s)
TypeError: string argument without an encoding
>>> bytes(s,encoding='utf-8')
b'123'
# 或者使用str的encode()方法
>>> s.encode()
b'123'
複製代碼
bytes->str
>>> b = b'124'
>>> b
b'124'
>>> type(b)
<class 'bytes'>
>>> str(b,encoding='utf-8')
'124'
# 或使用bytes的decode()
>>> b.decode()
'124'
複製代碼
這些數據類型都是Python
自帶的,在實際開發中應該根據具體需求選擇合適的數據類型。例如當要存儲的元素類型是多種多樣的,那麼就應該使用list
或者tuple
。而array.array
相對來講擁有較好的空間性能,但它只能存儲單一類型。
我相信在不少業務場景中list
或tuple
是能夠知足需求的,只是其它數據結構也要有所瞭解,在咱們作一些基礎組件時,會考慮數據結構的性能,或者閱讀他人的代碼時,能作到心中有數。