关于我
编程界的一名小小程序猿,目前在一个创业团队任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
是能够知足需求的,只是其它数据结构也要有所了解,在咱们作一些基础组件时,会考虑数据结构的性能,或者阅读他人的代码时,能作到心中有数。