应仅在数据全为同类型数值、长度稳定、需与c交互或内存严重受限时用array;否则优先用list,因其灵活通用。

array 模块不能直接替代 list,但对纯同类型数值、内存敏感或需与 C 交互的场景,它比 list 节省约 50–80% 内存,且访问更快;前提是放弃动态类型、嵌套结构和通用方法(如 append() 的任意对象支持)。
什么时候该用 array.array 而不是 list
只在同时满足以下条件时考虑切换:
- 数据全是同一数值类型(如全
int或全float),且你知道具体精度('i'vs'l'、'f'vs'd') - 数组长度稳定或增长可控(
array扩容仍是 O(n),但无 list 那种 over-allocation 优化) - 需要传给 C 扩展、NumPy(通过
.buffer_info()或memoryview)、或写入二进制文件(.tofile()) - 明确观察到 list 占用内存过高(比如百万级
int存在明显 GC 压力或 RSS 上升)
常见误用:拿 array 存 [1, 2.5, 3] ——会报 TypeError: array() argument 1 must be a unicode character, not str,因为类型码必须显式指定且不可混用。
array 类型码选错的典型后果
类型码决定每个元素占多少字节和解释方式,选错轻则数据错乱,重则段错误(尤其用 .buffer_info() 传给 C 时):
-
'b'(有符号字节)存255→ 实际存为-1(溢出截断) -
'H'(无符号短整型)存负数 → 报OverflowError -
'f'(32 位 float)读写numpy.float64数据 → 精度丢失且字节错位 - 用
'd'(64 位 float)存大量小整数(如计数器)→ 浪费一倍内存,不如'L'(无符号长整型)
查表确认:运行 import array; help(array.array) 看 typecodes 文档,别凭记忆写 'i' 就以为是 int —— 它在 Windows 是 32 位,在 Linux x86_64 也是 32 位,但 'q' 才是平台无关的 64 位有符号整型。
从 list 迁移到 array 的实操要点
不是简单把 [] 换成 array('d', []),关键在初始化和后续操作:
- 初始化必须带类型码和可迭代对象:
a = array.array('i', [1, 2, 3]),空数组写array.array('i')(不加[]) - 追加元素只能用同类型值:
a.append(4)✅,a.append(3.14)❌(报TypeError) - 切片返回新
array,但拼接需用+(a + b),不能用extend()传 list —— 必须是array实例 - 转回 list 开销不小:
list(a)是 O(n) 拷贝,如只需遍历,直接for x in a:即可(无需转) - 文件 I/O 更高效:
a.tofile(f)比pickle.dump(list(a), f)快且体积小,但格式无兼容性保障
示例对比:
import array
# list 版本:每个 int 是 PyObject,含引用计数+类型指针,约 28 字节/元素
l = [i for i in range(100000)]
<h1>array 版本:纯 4 字节有符号整数('i'),共 ~400KB vs list 的 ~2.8MB</h1><p>a = array.array('i', range(100000))</p>
真正难的不是语法转换,而是判断「这个数值序列是否真的适合压成紧凑连续内存」——比如中间要频繁插入、或后续要 map 成字符串、或依赖 list 的 .index() / .count(),那 array 反而增加维护成本。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











