3.4. array — 序列化的固定类型结构 | 数据结构 |《python 3 标准库实例教程》| python 技术论坛-金年会app官方网

未匹配的标注

目的:有效的管理序列化的固定类型结构的数值型数据。

array 模块定义了一个与 list 非常相似的序列化数据结构,只是所有的成员都必须是相同的初始类型。支持的类型有:所有的数值型或者其他固定大小的初始类型,如 bytes 型。

对一些支持的类型可以参考以下表格。array 标准库的文档包含了完整的类型代码清单。

数组成员的类型代码

代码 类型 最小占用空间 (bytes)
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

初始化

 array 实例化时会用到一个参数,该参数描述允许的数据类型。并且在初始化时可能还要给数组赋一个初值。

array_string.py

import array
import binascii
s = b'this is the array.'
a = array.array('b', s)
print('as byte string:', s)
print('as array      :', a)
print('as hex        :', binascii.hexlify(a))

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

$ python3 array_string.py
as byte string: b'this is the array.'
as array      : array('b', [84, 104, 105, 115, 32, 105, 115, 32,
 116, 104, 101, 32, 97, 114, 114, 97, 121, 46])
as hex        : b'54686973206973207468652061727261792e'

操作数组

其它 python 序列可以执行的操作, array 都可以用相同的方式执行,包括扩展数组的操作。

array_sequence.py

import array
import pprint
a = array.array('i', range(3))
print('initial :', a)
a.extend(range(3))
print('extended:', a)
print('slice   :', a[2:5])
print('iterator:')
print(list(enumerate(a)))

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

$ python3 array_sequence.py
initial : array('i', [0, 1, 2])
extended: array('i', [0, 1, 2, 0, 1, 2])
slice   : array('i', [2, 0, 1])
iterator:
[(0, 0), (1, 1), (2, 2), (3, 0), (4, 1), (5, 2)]

数组和文件

使用高效编码的内置方法,可以将数组的内容写入文件,也可以将文件的内容读取到数组中。

array_file.py

import array
import binascii
import tempfile
a = array.array('i', range(5))
print('a1:', a)
# 将数字数组写入临时文件
output = tempfile.namedtemporaryfile()
a.tofile(output.file)  # 必须传递一个 *真正的* 文件
output.flush()
# 读取原始数据
with open(output.name, 'rb') as input:
    raw_data = input.read()
    print('raw contents:', binascii.hexlify(raw_data))
    # 将数据读取到一个数组中
    input.seek(0)
    a2 = array.array('i')
    a2.fromfile(input, len(a))
    print('a2:', a2)

这个例子演示了如何直接从一个二进制文件中读取数据「 raw, 」,而不是将其读入一个新的数组并将字节转换为适当的类型。

$ python3 array_file.py
a1: array('i', [0, 1, 2, 3, 4])
raw contents: 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('bytes:', binascii.hexlify(as_bytes))
a2 = array.array('i')
a2.frombytes(as_bytes)
print('a2:', a2)

 tobytes() 和 frombytes() 处理的都是字节字符串,而不是 unicode 字符串。

$ python3 array_tobytes.py
a1: array('i', [0, 1, 2, 3, 4])
bytes: b'0000000001000000020000000300000004000000'
a2: array('i', [0, 1, 2, 3, 4])

可供选择的字节顺序

如果数组中的数据不是按照本机字节顺序排列的,或者说如果在以不同的字节顺序(或通过网络)将数据发送给系统之前需要交换数据的位置,则可以在不迭代 python 元素的情况之下转换整个数组的排列顺序。

array_byteswap.py

import array
import binascii
def to_hex(a):
    chars_per_item = a.itemsize * 2  # 2 个16进制数字
    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)
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 hex', 'a1', 'a2 hex', '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 hex           a1       a2 hex           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

另请参阅

  •  --  struct 模块。
  •  -- numpy 是一个高效处理大数据集的 python 库。

本文章首发在 金年会app官方网 网站上。

本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 cc 协议,如果我们的工作有侵犯到您的权益,请及时联系金年会app官方网。

原文地址:https://learnku.com/docs/pymotw/the-fixe...

译文地址:https://learnku.com/docs/pymotw/the-fixe...

上一篇 下一篇
讨论数量: 0



暂无话题~
网站地图