Python并没有像其他语言那样直接提供了数组(array)这种数据结构,而是通过导入array模块来完成数组的相关操作。
在Python中没有直接引入数组,也是由于Python中提供了列表这种数据结构,支持像数组一样的元素插入、修改和删除等操作。
但Python列表中的元素可以具有不同的数据类型,这一点与数组是不同的。如果想即使如此,额外提供一种数据结构来解决这种问题也没有必要。
Python中的array模块允许我们创建一个具有数据类型约束的数组,而且Python的array模块仅支持几类数据类型。其支持的数据类型主要有以下几种:
类型码 | 对应的C类型 | Python类型 | 最小字节数 |
---|---|---|---|
'b' | signed char | int | 1 |
'B' | unsigned char | int | 1 |
'u' | Py_UNICODE | Unicode character | 2 |
'h' | signed short | int | 2 |
'H' | unsigned short | int | 2 |
'i' | signed int | int | 2 |
'I' | unsigned int | int | 2 |
'l' | signed long | int | 4 |
'L' | unsigned long | int | 4 |
'q' | signed long long | int | 8 |
'Q' | unsigned long long | int | 8 |
'f' | float | float | 4 |
'd' | float | float | 8 |
其中,'u' 对应Python中已过时的unicode字符(Py_UNICODE),这种类型在Python3.3中被弃用,也将在4.0中被删除。如此以来,在array模块中只剩下整数类型或float类型。
在创建和使用数组时,首先需要引入array模块。
创建数组的语法格式如下:
array.array( typecode[, initializer])
其含义是使用typecode给出数组元素的类型,并由initializer进行初始化。
typecode参数即是上表给出的类型码,用于指定数组元素的类型。
initializer是可选参数,用于初始化数组的参数,该参数必须是一个列表,或字节类对象或可迭代类型。
下面给出一些具体的例子。
import array
array1 = array.array('i', [11,12,13,14])
array2 = array.array('B', [97,98,99,49,50])
array3 = array.array('f', [1.1,1.2,1.3,1.4])
上面的例子创建了2个整型数组单精度的浮点数数组。
虽然,'B'在C中对应的是无符号字符类型,但在Python中对应的是int类型,所以其元素的类型需要是整数类型。
下面使用print输出数组的类型及用于初始化的元素,同时使用typecode属性可以获取创建数组时指定的类型字符。
print(array1)
print(array2)
print(array3.typecode)
print(array2.typecode)
print(type(array2))
输出结果如下:
array('i', [11, 12, 13, 14])
array('b', [97, 98, 99, 49, 2])
f
b
<class 'array.array'>
上面的例子中,type()函数是一个内置函数,用于输出对象的类型。
我们可以使用循环语句输出数组中的每个元素,也可以使用数组索引来访问数组中的特定元素。
import array
ara = array.array('i', [11,12,13,14])
for e in ara:
print(e)
print(f'ara[2] = {ara[2]}/n') #输出索引为2的元素值
#使用索引循环输出每个元素
for i in range(0, len(ara)):
print(f'ara[{i}] = {ara[i]}')
结果如下:
11
12
13
14
ara[2] = 13
ara[0] = 11
ara[1] = 12
ara[2] = 13
ara[3] = 14
注意:python的数组索引也是从0开始的,如果索引越界,将引发IndexError错误。
我们可以使用insert()函数在数组指定索引处插入一个新元素,指定索引处的原元素将向后(右)移动一个位置。insert()函数的语法格式如下:
array.insert(i, x)
在数组 array 的 i 位置之前插入一个新元素 x 。 i 代表插入的位置, x 代表要插入的元素值。
我们也可以使用append()函数在数组末尾追加一个元素。append()函数的语法格式如下:
array.append(x)
在数组array的尾端追加一个新元素 x 。即, x 为要追加的元素值。
下面是两个函数使用的一个例子:
import array
a = array.array('i',[11,12,13,14])
print(f'原数组:{a}')
a.insert(2, 131)
print(f'插入元素后:{a}')
a.append(15)
print(f'追加新元素后:{a}')
输出结果如下:
原数组:array('i', [11, 12, 13, 14])
插入元素后:array('i', [11, 12, 131, 13, 14])
追加新元素后:array('i', [11, 12, 131, 13, 14, 15])
我们可以使用remove()函数删除指定的元素。remove函数的语法格式如下:
array.remove(x)
该函数的作用是从数组array中删除第一个值为 x 的元素。
import array
array4 = array.array('i', [11,12,13,14,13])
print(f'删除前:{array4}')
array4.remove(13)
print(f'删除后:{array4}')
执行结果如下所示:
删除前:array('i', [11, 12, 13, 14, 13])
删除后:array('i', [11, 12, 14, 13])
我们也可以使用pop()函数移除指定位置处的元素。pop函数的语法如下:
return_value = array.pop([i])
该函数的作用是移除索引 i 处的元素,并返回该元素值。 i 默认为 -1,即省略i时,默认是移除数组尾端的元素。
import array
array5 = array.array('i', [11,12,13,14,15])
print(f'操作前:{array5}')
rtn = array5.pop()
print(f'操作后:{array5},移除的元素为:{rtn}')
rtn = array5.pop(2)
print(f'array5.pop(2)={rtn},操作后的数组:{array5}')
运行的结果如下:
操作前:array('i', [11, 12, 13, 14, 15])
操作后:array('i', [11, 12, 13, 14]),移除的元素为:15
array5.pop(2)=13,操作后的数组:array('i', [11, 12, 14])
注意:在使用remove进行操作时,如果指定的元素值在数组中不存在时会引发ValueError错误。
我们可以使用Index()函数在数组中查找指定的元素值。index()函数的语法格式如下:
array.index(x[, start[, stop]])
其中,x为要查找的元素值,start为搜索的起始位置,stop为搜索的停止位置。
该函数将返回第一个匹配的元素索引,如果数组中不存在指定的x值,将引发ValueError错误。
下面是index()函数使用的一个例子:
import array
array6 = array.array('i',[11,12,13,14,15])
pos = array6.index(13)
try:
print(f'13的索引是{pos}')
except ValueError as ve:
print('数组中不存在13')
运行结果如下:
13的索引是2
我们可以使用数组索引的方式通过赋值来修改数组指定索引处的值。
import array
array7 = array.array('i', [11, 12, 13, 14, 15])
array7[2] = 3
array7[3] = 4
print(f'修改后的数组为:{array7}')
try:
array7[5] = 5
except IndexError as ie:
print('数组索引使用出现错误。')
输出结果如下:
修改后的数组为:array('i', [11, 12, 3, 4, 15])
数组索引使用出现错误。
我们可以使用extend()函数将一个可迭代对象追加到数组的尾端。
extend()函数的语法格式如下:
array.extend(iterable)
从iterable中为数组尾端追加新元素。如果iterable是数组的话,iterable必须与被追加元素的数组具有相同的类型码,否则,将引发TypeError错误;如果iterable不是数组,则iterable必须是可迭代的,同时iterable的元素类型需与数组具有相同的类型。
import array
array8 = array.array('i', [11,12,13])
array9 = array.array('i', [14,15,16,17])
array8.extend(array9)
print(array8)
array9.extend([18,19])
print(array9)
array9.extend(set([20,21,22]))
print(array9)
输出结果如下:
array('i', [11, 12, 13, 14, 15, 16, 17])
array('i', [14, 15, 16, 17, 18, 19])
array('i', [14, 15, 16, 17, 18, 19, 20, 21, 22])
数组也支持负向索引,即从后端开始访问数组中的元素。数组元素、正向索引及负向索引的关系可以由下图来表示。
import array
array_a = array.array('i', [11, 12, 13, 14, 15, 16, 17, 18, 19, 20])
print(f'array_a[9] = {array_a[9]}');
print(f'array_a[-1] = {array_a[-1]}');
输出结果如下:
array_a[9] = 20
array_a[-1] = 20
Python数组也支持切片操作,返回数组若干元素的一个新数组。此操作不会改变原数组。同时切片操作也支持负向索引。
import array
array_b = array.array('i', [1, 2, 3 ,4, 5, 6, 7])
print(array_b[2:])
print(array_b[2:5])
print(array_b[:4])
print(array_b[-3:])
print(array_b[-5:-2])
print(array_b[:-2])
输出结果如下:
array('i', [3, 4, 5, 6, 7])
array('i', [3, 4, 5])
array('i', [1, 2, 3, 4])
array('i', [5, 6, 7])
array('i', [3, 4, 5])
array('i', [1, 2, 3, 4, 5])
关于Python切片操作的更多知识可以参看本站中的另外一篇文章:全面掌握Python字符串切片方法
我们可以使用count()函数返回数组中特定元素的个数。
import array
array_c = array.array('i', [11,12,11,13,12,11])
print(array_c.count(11)) # 3
print(array_c.count(15)) # 0
我们可以使用reverse()函数对数组进行翻转操作。即翻转数组元素的顺序。
import array
array_d = array.array('i', [11, 12, 13, 14, 15])
array_d.reverse()
print(array_d)
输出结果如下:
array('i', [15, 14, 13, 12, 11])
我们可以使用tolist()函数把数组转换成具有相同项的普通列表。
import array
array_e = array.array('i', [11, 12, 13, 14, 15])
lst = array_e.tolist()
print(lst)
输出结果如下:
[11, 12, 13, 14, 15]
我们可以使用Python内置函数len()获取数组中元素的个数。
import array
array_f = array.array('i', [11, 12, 13, 14, 15])
print(len(array_f)) # 5
我们可以使用array.itemsize来获取数组中每个元素所占的字节数。
import array
array_g = array.array('i', [11, 12, 13, 14, 15])
print(array_g.itemsize) # 4
array_h = array.array('q', [11, 12, 13, 14, 15])
print(array_h.itemsize) # 8
新闻热点
疑难解答