Python:array数组比列表list更高效

Python:array数组比列表list更高效

编码文章call10242025-09-22 15:46:221A+A-

大家好,我是科雷!

在Python中,除了我们常用的列表(list),还有一个专门用于处理同类型数据的高效工具array库。相比于列表,array数组在存储和操作同类型数据时更加节省内存、运算速度更快,非常适合处理大量数值型数据。

与列表不同点:

1)array数组只能存储同一类型的数据。

2)array主要用于处理数字(正数或浮点数),或者单个unicode字符,不支持字符串或者其他数据类型,处理的数据类型不像list列表一样丰富。

本文将详细介绍array库的核心功能和常用函数,帮助你快速掌握这个高效数据处理工具。

一、array库基础

array库是 Python 的标准库,无需额外安装,使用前需先导入:

import array

array库的核心是array.array类,用于创建和操作数组。

二、重点函数详解

1.array.array ():创建数组

这是最基础也是最常用的函数,用于创建一个新的数组。

参数说明

  • typecode:必填,单字符字符串,指定数组中元素的类型(见下表)
  • initializer:可选,初始化数据,可以是列表、元组或可迭代对象

常用typecode类型:包含整数、浮点数、unicode字符

typecode

对应的 Python 类型

描述(C 语言中的对应类型)

字节数

取值范围(数值类型)

'b'

int

有符号字符(signed char)

1

-128 到 127

'B'

int

无符号字符(unsigned char)

1

0 到 255

'h'

int

有符号短整数(short)

2

-32768 到 32767

'H'

int

无符号短整数(unsigned short)

2

0 到 65535

'i'

int

有符号整数(int)

2 或 4

取决于系统位数

'I'

int

无符号整数(unsigned int)

2 或 4

取决于系统位数

'l'

int

有符号长整数(long)

4

-2147483648 到 2147483647

'L'

int

无符号长整数(unsigned long)

4

0 到 4294967295

'q'

int

有符号长 long 整数(long long)

8

-9223372036854775808 到 9223372036854775807

'Q'

int

无符号长 long 整数(unsigned long long)

8

0 到 18446744073709551615

'f'

float

单精度浮点数(float)

4

约 ±3.4e±38(6-7 位有效数字)

'd'

float

双精度浮点数(double)

8

约 ±1.8e±308(15-17 位有效数字)

'u'

str(单个字符)

Unicode 字符(wchar_t)

2 或 4

取决于系统的 wchar_t大小(通常为2字节或4字节)

案例 1:创建不同类型的数组

import array

# 创建整数数组
int_array = array.array('i', [1, 2, 3, 4, 5])
print("整数数组:", int_array)  # 输出: array('i', [1, 2, 3, 4, 5])

# 创建浮点数数组
float_array = array.array('d', [1.1, 2.2, 3.3])
print("浮点数数组:", float_array)  # 输出: array('d', [1.1, 2.2, 3.3])

# 创建空数组
empty_array = array.array('b')
print("空数组:", empty_array)  # 输出: array('b')

# 创建单个unicode字符数组
alist = array.array('u',['a','d'])
print("字符数组:", alist)  # 输出: array('u', 'ad')

#创建不符合类型的数组会报错
    alist = array.array('i',['a','d'])
#报错:
TypeError: 'str' object cannot be interpreted as an integer

2.append ():添加元素到数组末尾

参数说明

  • x:必填,要添加的元素(必须与数组类型一致)
import array

my_array = array.array('i', [1, 2, 3])
my_array.append(4)
my_array.append(5)
print(my_array)  # 输出: array('i', [1, 2, 3, 4, 5])

3.extend ():扩展数组

功能:将另一个数组或可迭代对象的元素添加到当前数组末尾

参数说明

  • iterable:必填,要添加的可迭代对象(元素类型必须与数组一致)
import array

arr1 = array.array('i', [1, 2, 3])
arr2 = array.array('i', [4, 5, 6])

arr1.extend(arr2)
print(arr1)  # 输出: array('i', [1, 2, 3, 4, 5, 6])

# 也可以扩展列表(元素类型需一致)
arr1.extend([7, 8, 9])
print(arr1)  # 输出: array('i', [1, 2, 3, 4, 5, 6, 7, 8, 9])

4.insert ():插入元素

功能:在指定位置插入一个元素

参数说明

  • i:必填,插入位置的索引
  • x:必填,要插入的元素(必须与数组类型一致)

案例

import array

my_array = array.array('i', [1, 2, 3, 4])
my_array.insert(2, 100)  # 在索引2处插入100
print(my_array)  # 输出: array('i', [1, 2, 100, 3, 4])

5.pop ():移除并返回元素

功能:移除并返回指定位置的元素,默认移除最后一个元素

参数说明

  • i:可选,要移除元素的索引,默认为 - 1(最后一个元素)
import array

my_array = array.array('i', [10, 20, 30, 40])

# 移除最后一个元素
last = my_array.pop()
print("移除的元素:", last)  # 输出: 40
print("操作后数组:", my_array)  # 输出: array('i', [10, 20, 30])

# 移除指定索引的元素
first = my_array.pop(0)
print("移除的元素:", first)  # 输出: 10
print("操作后数组:", my_array)  # 输出: array('i', [20, 30])

6.remove ():移除指定值的元素

功能:移除数组中第一个出现的指定值元素

参数说明

  • x:必填,要移除的元素值
import array

my_array = array.array('i', [10, 20, 30, 20, 40])
my_array.remove(20)  # 移除第一个20
print(my_array)  # 输出: array('i', [10, 30, 20, 40])

7.fromlist ():从列表添加元素

功能:将列表中的元素添加到数组中

参数说明

  • list:必填,要添加的列表(元素类型必须与数组一致)
import array

my_array = array.array('i', [1, 2, 3])
my_list = [4, 5, 6]

my_array.fromlist(my_list)
print(my_array)  # 输出: array('i', [1, 2, 3, 4, 5, 6])

8.tolist ():转换为列表

功能:将数组转换为普通列表

参数说明:无

import array

my_array = array.array('i', [1, 2, 3, 4, 5])
my_list = my_array.tolist()

print("转换后的列表:", my_list)  # 输出: [1, 2, 3, 4, 5]
print("列表类型:", type(my_list))  # 输出: <class 'list'>

三、常用函数补充

1.buffer_info ():获取数组内存信息

功能:返回一个元组(address, length),表示数组在内存中的地址和元素个数

import array

my_array = array.array('i', [1, 2, 3, 4, 5])
print(my_array.buffer_info())  
# 输出: (4492531344, 5),内存地址每次运行可能不同

2.byteswap ():交换字节顺序

功能byteswap() 函数用于对数组中每个元素的字节顺序进行反转,这是一个专门用于处理跨平台数据交互的底层操作。仅对多个字节数据有效,单字节类型(如 'b'、'B')的元素没有字节顺序问题,调用 byteswap() 不会产生任何变化。

什么是字节顺序?

字节顺序(又称 "端序")指的是多字节数据在内存中的存储顺序,主要有两种形式:

  • 大端序(Big-endian):高位字节存放在低地址(如人类读写习惯,先存高位)
  • 小端序(Little-endian):高位字节存放在高地址(与人类读写习惯相反)

不同硬件平台字节顺序可能不同(如 x86 是小端序,某些嵌入式设备是大端序)。

例如,整数 0x1234(十六进制,十进制为 4660)在内存中的存储:

  • 大端序:0x12(高位)存放在低地址,0x34(低位)存放在高地址
  • 小端序:0x34(低位)存放在低地址,0x12(高位)存放在高地址
import array

# 创建一个2字节有符号整数数组('h'类型)
# 0x1234 表示十进制 4660
arr = array.array('h', [0x1234])
print("原始数组:", arr)  # 输出: array('h', [4660])

# 执行字节交换
arr.byteswap()
print("字节交换后:", arr)  # 输出: array('h', [873594880])
# 873594880 对应的十六进制是 0x3412,正好是 0x1234 的字节反转

3.count ():统计元素出现次数

功能:返回指定元素在数组中出现的次数

参数说明

  • x:必填,要统计的元素值
import array

my_array = array.array('i', [1, 2, 2, 3, 2, 4])
print("2出现的次数:", my_array.count(2))  # 输出: 3

4.index ():查找元素索引

功能:返回指定元素在数组中第一次出现的索引

参数说明

  • x:必填,要查找的元素值
import array

my_array = array.array('i', [10, 20, 30, 20, 40])
print("20第一次出现的索引:", my_array.index(20))  # 输出: 1

5.reverse ():反转数组

功能:原地反转数组中的元素顺序

import array

my_array = array.array('i', [1, 2, 3, 4, 5])
my_array.reverse()
print("反转后的数组:", my_array)  # 输出: array('i', [5, 4, 3, 2, 1])

6.typecode:查看数组类型

功能:属性(非函数),返回数组的类型代码

import array

int_arr = array.array('i', [1, 2, 3])
float_arr = array.array('d', [1.1, 2.2])

print("int_arr类型:", int_arr.typecode)  # 输出: i
print("float_arr类型:", float_arr.typecode)  # 输出: d

7.itemsize:查看元素字节大小

功能:属性(非函数),返回数组中每个元素的字节大小。实际大小跟上面表中列出的大小不一定相同。

import array

int_arr = array.array('i', [1, 2, 3])  # 'i'类型占2字节
long_arr = array.array('l', [1, 2, 3])  # 'l'类型占4字节

print("int_arr元素大小:", int_arr.itemsize)  # 输出: 4
print("long_arr元素大小:", long_arr.itemsize)  # 输出: 8

8.clear() :从数组中移除所有元素。

官网说在python3.13版本中增加,由于我本地版本较低,没有试过,看过文章的朋友可以自己试下。

四 array库和list使用对比

1)、内存占用对比:array 更节省空间

列表(list)存储的是对象引用(即使存储基本类型,也会被包装成 Python对象),每个引用额外占用内存;而array直接存储原始二进制数据,仅占用数据本身的空间。

举例:存储 100 万个整数时的内存占用

import array
import sys

# 创建包含100万个整数的列表
list_data = [i for i in range(1000000)]

# 创建相同数据的array('i'类型,2字节整数)
array_data = array.array('i', range(1000000))

# 计算内存占用(近似值)
print(f"列表内存:{sys.getsizeof(list_data) + sum(sys.getsizeof(x) for x in list_data)} 字节")
print(f"array内存:{sys.getsizeof(array_data)} 字节")

结果:列表内存比array内存大了9倍

列表内存:36448724 字节

array内存:4091948 字节

2)、运算速度对比:array 处理数值更快

由于array存储的是连续的原始数据,无需像列表那样处理对象引用和类型检查,因此在批量数值操作时速度更快。

举例:在 100 万个元素中插入一个数字

import array
import time

# 准备数据
n = 1000000
list_data = list(range(n))
array_data = array.array('i', range(n))

# 测试列表累加
start = time.time()
list_data.insert(299333,1)
list_time = time.time() - start

# 测试array累加
start = time.time()
array_data.insert(299333,1)
array_time = time.time() - start

print(f"列表插入时间:{list_time:.6f}秒")
print(f"array插入时间:{array_time:.6f}秒")
print(f"array速度提升:{list_time / array_time:.2f}倍")

结果:

列表插入时间:0.004367秒

array插入时间:0.000105秒

array速度提升:41.63倍

3)适用场景对比:各有优势

场景

array 优势

列表优势

数据类型

仅同类型数据(适合数值、字符)

可混合存储任意类型(int、str、对象等)

内存敏感场景

占用空间小,适合大数据集

占用空间大,但灵活性高

数值运算

处理速度快,适合批量计算

速度较慢,但支持更多复杂操作

功能丰富度

方法较少,专注于基础操作

内置方法多(如 sort()、count() 等)

跨平台数据交互

支持二进制读写和字节交换(byteswap())

需额外序列化(如 pickle)

五、何时选择 array?

当你需要处理大量同类型数值数据(如传感器读数、统计数据),且关注内存占用处理速度时,array 是更好的选择。
如果需要存储不同类型数据,或依赖列表的丰富功能(如嵌套、动态类型转换),则应使用列表。

简单来说:array 是 “轻量高效的数值容器”,列表是 “通用灵活的多类型容器”

点击这里复制本文地址 以上内容由文彬编程网整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!
qrcode

文彬编程网 © All Rights Reserved.  蜀ICP备2024111239号-4