Автор оригинала: Doug Hellmann.
Цель:
Эффективно управляйте последовательностями числовых данных фиксированного типа.
Модуль array
определяет структуру данных последовательности, которая очень похожа на list
, за исключением того, что все элементы должны быть одного и того же примитивного типа. Поддерживаются все числовые или другие примитивные типы фиксированного размера, например байты.
В таблице ниже указаны некоторые из поддерживаемых типов. Документация стандартной библиотеки для array
включает полный список кодов типов.
Коды типов для членов массива
Код
Тип
Минимальный размер (байты)
int
int
подписанный короткий
беззнаковый короткий
подписанный int
беззнаковое целое
подписан долго
беззнаковый длинный
подписан долго
беззнаковый длинный длинный
плавать
двойной поплавок
Инициализация
Экземпляр 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'
Управление массивами
array
можно расширять и манипулировать другими способами так же, как и другими последовательностями Python.
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) # Write the array of numbers to a temporary file output tempfile.NamedTemporaryFile() a.tofile(output.file) # must pass an *actual* file output.flush() # Read the raw data with open(output.name, 'rb') as input: raw_data input.read() print('Raw Contents:', binascii.hexlify(raw_data)) # Read the data into an array 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]) 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])
Альтернативный порядок байтов
Если данные в массиве находятся не в собственном порядке байтов или если данные необходимо поменять местами перед отправкой в систему с другим порядком байтов (или по сети), можно преобразовать весь массив без
array_byteswap.py
import array import binascii def to_hex(a): chars_per_item a.itemsize * 2 # 2 hex digits 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 – модуль
struct
. - Числовой Python – NumPy – это библиотека Python для эффективной работы с большими наборами данных.
- Заметки о переносе Python 2 на 3 для массива