大数跨境
0
0

【Python】array — 固定类型数据序列

【Python】array — 固定类型数据序列 我爱数据科学
2025-10-12
2
导读:用途:高效管理固定类型的数值数据序列。

用途高效管理固定类型的数值数据序列。

array 模块定义了一种序列数据结构,其外观与列表(list)非常相似,不同之处在于:该结构中所有元素必须是相同的基本类型(primitive type)。支持的类型包括所有数值类型或其他固定大小的基本类型(如字节类型 bytes)。

数组元素的类型码(Type Codes for array Members)

下表列出了部分支持的类型,array 模块的标准库文档中提供了完整的类型码列表。

类型码(Code)
类型(Type)
最小大小(字节,Minimum size)
b
有符号整数(int)
1
B
无符号整数(int)
1
h
有符号短整数(signed short)
2
H
无符号短整数(unsigned short)
2
i
有符号整数(signed int)
2
I
无符号整数(unsigned int)
2
l
有符号长整数(signed long)
4
L
无符号长整数(unsigned long)
4
q
有符号超长整数(signed long long)
8
Q
无符号超长整数(unsigned long long)
8
f
单精度浮点数(float)
4
d
双精度浮点数(double float)
8

初始化(Initialization)

实例化数组时,需传入一个参数指定允许存储的数据类型,还可选择性传入初始数据序列以存储到数组中。

示例代码:array_string.py

import array
import binascii

s = b'This is the array.'  # 定义字节字符串
a = array.array('b', s)    # 初始化数组:类型码 'b'(字节),初始数据为 s

print('作为字节字符串:', s)
print('作为数组      :', a)
print('作为十六进制  :', binascii.hexlify(a))

在该示例中,数组被配置为存储字节序列,并使用简单的字节字符串进行初始化。

运行结果

$ python3 array_string.py

作为字节字符串: b'This is the array.'
作为数组      : array('b', [84, 104, 105, 115, 32, 105, 115, 32, 116, 104, 101, 32, 97, 114, 114, 97, 121, 46])
作为十六进制  : b'54686973206973207468652061727261792e'

操作数组(Manipulating Arrays)

数组可通过与其他 Python 序列相同的方式进行扩展或其他操作。

示例代码:array_sequence.py

import array
import pprint

a = array.array('i', range(3))  # 初始化数组:类型码 'i'(有符号整数),初始数据为 0、1、2
print('初始状态 :', a)

a.extend(range(3))  # 扩展数组:添加 0、1、2
print('扩展后   :', a)

print('切片结果 :', a[2:5])  # 切片操作:获取索引 2 到 4 的元素

print('迭代器   :')
print(list(enumerate(a)))  # 枚举数组元素(索引+值)

支持的操作包括切片、迭代和向末尾添加元素等。

运行结果

$ python3 array_sequence.py

初始状态 : array('i', [0, 1, 2])
扩展后   : array('i', [0, 1, 2, 0, 1, 2])
切片结果 : array('i', [2, 0, 1])
迭代器   :
[(0, 0), (1, 1), (2, 2), (3, 0), (4, 1), (5, 2)]

数组与文件(Arrays and Files)

数组的内容可通过内置方法写入文件或从文件读取,这些方法为该用途进行了高效的代码实现。

示例代码:array_file.py

import array
import binascii
import tempfile

a = array.array('i', range(5))  # 初始化数组:数据为 0、1、2、3、4
print('A1:', a)

# 将数组写入临时文件
output = tempfile.NamedTemporaryFile()
a.tofile(output.file)  # 必须传入一个“实际的文件对象”
output.flush()  # 刷新缓冲区,确保数据写入文件

# 读取文件中的原始数据
with open(output.name, 'rb'as input:
    raw_data = input.read()  # 读取原始二进制数据
    print('原始内容:', binascii.hexlify(raw_data))

    # 将数据读入新数组
    input.seek(0)  # 移动文件指针到开头
    a2 = array.array('i')  # 初始化空数组(类型与原数组一致)
    a2.fromfile(input, len(a))  # 从文件读取指定长度的数据
    print('A2:', a2)

该示例对比了两种读取方式:一是“原始读取”(直接从二进制文件读取数据),二是将数据读入新数组并将字节转换为相应类型。

运行结果

$ python3 array_file.py

A1: array('i', [0, 1, 2, 3, 4])
原始内容: b'0000000001000000020000000300000004000000'
A2: array('i', [0, 1, 2, 3, 4])

tofile() 方法通过 tobytes() 格式化数据,而 fromfile() 方法通过 frombytes() 将数据转换回数组实例。

示例代码:array_tobytes.py

import array
import binascii

a = array.array('i', range(5))  # 初始化数组
print('A1:', a)

as_bytes = a.tobytes()  # 将数组转换为字节字符串
print('字节序列:', binascii.hexlify(as_bytes))

a2 = array.array('i')  # 初始化空数组
a2.frombytes(as_bytes)  # 从字节字符串恢复数组
print('A2:', a2)

注意:tobytes() 和 frombytes() 均作用于字节字符串(byte string),而非 Unicode 字符串。

运行结果

$ python3 array_tobytes.py

A1: array('i', [0, 1, 2, 3, 4])
字节序列: b'0000000001000000020000000300000004000000'
A2: array('i', [0, 1, 2, 3, 4])

字节序转换(Alternative Byte Ordering)

若数组中的数据不是本机字节序,或数据在发送到字节序不同的系统(或通过网络发送)前需要交换字节序,可直接转换整个数组,无需在 Python 中遍历元素。

示例代码:array_byteswap.py

import array
import binascii


def to_hex(a):
    """将数组转换为十六进制字符串的生成器"""
    chars_per_item = a.itemsize * 2# 每个元素对应 2 个十六进制字符
    hex_version = binascii.hexlify(a)
    num_chunks = len(hex_version) // chars_per_item
    for i in range(num_chunks):
        start = i * chars_per_item
        end = start + chars_per_item
        yield hex_version[start:end]


# 定义初始值和结束值
start = int('0x12345678'16)  # 十六进制转十进制:305419896
end = start + 5
a1 = array.array('i', range(start, end))  # 原数组
a2 = array.array('i', range(start, end))  # 用于字节序转换的数组
a2.byteswap()  # 交换数组元素的字节序

# 打印表头
fmt = '{:>12} {:>12} {:>12} {:>12}'
print(fmt.format('A1 十六进制''A1 数值''A2 十六进制''A2 数值'))
print(fmt.format('-' * 12'-' * 12'-' * 12'-' * 12))
# 打印每行数据
fmt = '{!r:>12} {:12} {!r:>12} {:12}'
for values in zip(to_hex(a1), a1, to_hex(a2), a2):
    print(fmt.format(*values))

byteswap() 方法在 C 语言层面交换数组元素的字节序,因此比在 Python 中遍历数据效率高得多。

运行结果

$ python3 array_byteswap.py

      A1 十六进制        A1 数值       A2 十六进制        A2 数值
------------ ------------ ------------ ------------
 b'78563412'    305419896  b'12345678'   2018915346
 b'79563412'    305419897  b'12345679'   2035692562
 b'7a563412'    305419898  b'1234567a'   2052469778
 b'7b563412'    305419899  b'1234567b'   2069246994
 b'7c563412'    305419900  b'1234567c'   2086024210

【声明】内容源于网络
0
0
我爱数据科学
精通R语言及Python,传递数据挖掘及可视化技术,关注机器学习及深度学习算法及实现,分享大模型及LangChain的使用技巧。编著多本R语言、python、深度学习等书籍。
内容 322
粉丝 0
我爱数据科学 精通R语言及Python,传递数据挖掘及可视化技术,关注机器学习及深度学习算法及实现,分享大模型及LangChain的使用技巧。编著多本R语言、python、深度学习等书籍。
总阅读84
粉丝0
内容322