一文读懂Python中所有类数组数据类型:list、tuple、array及转换
本文系统梳理Python中常见的类数组数据结构,包括可变列表list、不可变元组tuple、定长数组array.array以及字符串序列str、bytes和bytearray。详细对比它们在内存占用、可变性及元素类型限制上的差异,并提供各类型间相互转换的代码示例,帮助开发者根据性能与功能需求选择合适的数据结构。
Python数组类型概览
前言
数组结构是各类编程语言的基础组件,本文将盘点Python中实现“数组”概念的多种数据类型。
- list
- tuple
- array.array
- str
- bytes
- bytearray
严格来说,将上述类型统称为“数组”并不准确。此处将数组视为广义概念,涵盖列表、序列及数组等类数组(array-like)数据类型。
注:本文所有代码示例均在Python 3.7环境下运行。
可变动态列表list
0x00 可变动态列表list
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
0x01 不可变元组tuple
tuple的操作逻辑与list相似,但具备不可变性,不支持扩容,可存储任意Python对象,同样无需指定元素类型。
>>> 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
执行+运算后,原对象与新对象的内存地址不同。
定长数组array.array
0x02 array.array
若需在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 |
字符串与字节序列处理
0x03 字符串序列str
在Python 3中,使用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
0x04 bytes
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
0x05 bytearray
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
数据类型相互转换
0x06 各类型相互转换 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'
总结与参考资料
0x07 总结
上述数据类型均为Python内置类型,实际开发中应根据具体需求选择合适的数据结构。例如,当存储元素类型多样时,应选用list或tuple;而array.array具有较好的空间性能,但仅能存储单一类型。 在许多业务场景中,list或tuple已能满足需求,但了解其他数据结构有助于在开发基础组件时考量性能,或在阅读他人代码时做到心中有数。
0x08 学习资料
- docs.python.org/3.1/library…
- docs.python.org/zh-cn/3/lib…
- docs.python.org/3/library/s…
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对本站的支持。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









