专业编程基础技术教程

网站首页 > 基础教程 正文

一文搞懂Python中的所有数组数据类型

ccvgpt 2024-08-07 19:00:56 基础教程 11 ℃

关于我

一个有思想的程序猿,终身学习实践者,目前在一个创业团队任team lead,技术栈涉及Android、Python、Java和Go,这个也是我们团队的主要技术栈。

一文搞懂Python中的所有数组数据类型

Github:https://github.com/hylinux1024

微信公众号:终身开发者(angrycode)

数组类型是各种编程语言中基本的数组结构了,本文来盘点下Python中各种“数组”类型的实现。

  • list
  • tuple
  • array.array
  • str
  • bytes
  • bytearray

其实把以上类型都说成是数组是不准确的。这里把数组当作一个广义的概念,即把列表、序列、数组都当作array-like数据类型来理解。

注意本文所有代码都是在Python3.7中跑的\^_^

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]

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

可以看出tuple执行+运算符之后两个对象的地址是不一样

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 codeC TypePython Type‘b’signed charint‘B’unsigned charint‘u’Py_UNICODEUnicode character‘h’signed shortint‘H’unsigned shortint‘i’signed intint‘I’unsigned intint‘l’signed longint‘L’unsigned longint‘q’signed long longint‘Q’unsigned long longint‘f’floatfloat‘d’doublefloat

0x03 字符串序列str

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

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 学习资料

  • https://docs.python.org/3.1/library/functions.html#bytearray
  • https://docs.python.org/zh-cn/3/library/array.html
  • https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str

Tags:

最近发表
标签列表