赞
踩
数组是编程语言中的基本数据结构,在很多算法中都有广泛的应用。本文介绍一些Python的数组实现,这些数组只用到了语言的核心特性或Python标准库包含的功能。
另外,会介绍这些实现的优缺点,在合适的场景选择合适的实现方式。在了解这些知识前,需要清楚数组是有大小固定的记录组成,根据索引能找到每个元素, 并且这些元素是存储在连续的内存块中的,所以它是连续的数据结构。
列表(list)是一种可以添加删除元素的数组实现,还能分配和释放内存来自动调整存储空间,列表中可以包含任意类型的元素,并且可以混合存储。
arr = ['one', 'two', 'three'] print(arr[0]) # 列表的__repr__方法能使列表打印更加直观 print(arr) # 列表元素可变 arr[0] = 'hello' print(arr) # 删除元素 del arr[0] print(arr) # 添加不同类型的元素 arr.append(1) print(arr)
以上代码运行结果:
one
['one', 'two', 'three']
['hello', 'two', 'three']
['two', 'three']
['two', 'three', 1]
关于 python list 的更多用法请点击 此链接
元组(tuple)也是Python语言核心的一部分。但与列表不同的是,元组对象是不可变的,不能添加,修改,删除元素,所有元素必须在对象创建时定义。
与列表一样,元素可以包含不同类型的元素,意味着数据的打包密度比固定类型的数组小。
arr = 'one', 'two', 'three' print(arr[0]) # 元组的__repr__方法同样能使元组打印更加直观 print(arr) # 元组元素不可变 # arr[0] = 'hello' # 抛出异常 TypeError: 'tuple' object does not support item assignment # 元组元素不可删除 # del arr[0] # 抛出异常 TypeError: 'tuple' object doesn't support item deletion # 元组元素可以含有任意类型的数据 # 添加元素会产生新元组 arr1 = arr + (1,) print(arr1) print(arr.__hash__()) print(arr1.__hash__())
以上代码运行结果
one
('one', 'two', 'three')
('one', 'two', 'three', 1)
-7698655770510080900
1375085398319489189
关于 tuple 的更多使用文档请点击 此链接
Python array模块用于存储C语言风格的基本数据类型(字节,32位整数,浮点数等),使用该类型创建的数组是可变的,行为与列表相似,但是有一个重要的区别是:这种数组是单一数据类型的“类型数组”, 由于有类型单一的限制,这种数组比元组和列表更加节省存储空间。存储在其中的元素紧密排列,不会有因为元素占用空间不一样导致元素间内存浪费。
arr = array.array('i', (1, 2, 3)) print(arr[0]) # 数组的__repr__方法同样能使数组打印更加直观 print(arr) # 数组元素可变 arr[1] = 6 print(arr) # 数组元素可以删除 del arr[1] print(arr) # 添加元素 arr.append(10) print(arr) # 数组中元素类型是固定的 # arr[1] = 'hello' # 抛出异常 TypeError: an integer is required (got type str)
以上代码运行结果
1
array('i', [1, 2, 3])
array('i', [1, 6, 3])
array('i', [1, 3])
array('i', [1, 3, 10])
Python3.x 使用str对象将文本存储为不可变的Unicode字符序列,这意味着str是不可变的字符数组,str是一种递归数据结构,字符串中的每个元素都是长度为1的str对象
由于字符串对象存储单一数据类型,因为很节省空间,适合用来存储Unicode文本。因为字符串在Python中是不可变的,所有修改字符串需要有一个副本,可以用存储单个字符串的列表来实现这种“可变字符串”。
arr = 'hello' print(arr[0]) print(arr) # 字符串是不可变的 # arr[1] = 'e' # 抛出异常 TypeError: 'str' object does not support item assignment # 字符串中字符不可删除 # del arr[1] # 抛出异常 TypeError: 'str' object doesn't support item deletion # 可以解包到列表中,产生可变版本 str_list = list(arr) print(str_list) print(''.join(str_list)) # 字符串是递归数据类型 print(type('abc')) print(type('abc'[0]))
以上代码运行结果:
h
hello
['h', 'e', 'l', 'l', 'o']
hello
<class 'str'>
<class 'str'>
bytes对象是单字节的不可变序列,单字节范围为0~255(含)之间的整数,bytes和str很像,可以认为是不可变的字节数组
bytes同样能通过字面语法进行创建,并且很节省空间。与字符串不一样的是,它有专门的可变字节数组,bytes可以解包到bytearray中。
arr = bytes((1, 2, 3, 4)) print(arr[0]) # 通过字符串加b前缀创建bytes print(arr) arr = b'\x01\x02\x03\x04' # bytes必须是0~255间的整数类型 # bytes((1, 2, 3, 300)) # 抛出异常 ValueError: bytes must be in range(0, 256) # bytes是不可变的 # arr[1] = 23 # 抛出异常 TypeError: 'bytes' object does not support item assignment # bytes中的元素不可删除 # del arr[1] # 抛出异常 TypeError: 'bytes' object doesn't support item deletion
以上代码运行结果
1
b'\x01\x02\x03\x04'
bytearray 类型是可变整数序列,包含的整数范围在0~255。bytearray与bytes关系密切,主要区别在于bytearray可以自由修改,如覆盖、删除先有元素和添加新元素,此时bytearray对象将相应的增长和缩小。
bytearary可以转回不可变的bytes对象,但是这需要复制所存储的数据,是耗时为O(n)的慢操作
arr = bytearray((0, 1, 2, 3)) print(arr[0]) print(arr) # bytearray是可变的 arr[1] = 23 print(arr) # bytearray可以增长或缩小 del arr[1] print(arr) arr.append(42) print(arr) # 只能是0~255间的整数类型 # arr[1] = 'hello' # 抛出异常 TypeError: 'str' object cannot be interpreted as an integer # arr[1] = 300 # 抛出异常 ValueError: byte must be in range(0, 256) # bytearray可以转回bytes数据类型 print(bytes(arr))
以上代码运行结果:
0
bytearray(b'\x00\x01\x02\x03')
bytearray(b'\x00\x17\x02\x03')
bytearray(b'\x00\x02\x03')
bytearray(b'\x00\x02\x03*')
b'\x00\x02\x03*'
对于上述几种不同的数组实现,在不同的场景有不同的选择,大致可以按照以下几点去选择对应的实现方式:
在大多数情况下优先选择列表实现,在性能或存储空间上有瓶颈,再考虑其他数据类型。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。