Как разделить байтовый массив или байтовый объект на 16-разрядные целые числа?

#python #arrays #python-3.x #split

Вопрос:

Учитывая bytearray объект длиной 2xN, как я могу получить список (или массив) из N 16-разрядных целых чисел из этого объекта?

Например, если ba определяется как:

 ba = bytearray([0x01, 0x02, 0x01, 0x03, 0xff, 0xff])
 

Затем, после преобразования, результат должен быть таким:

 ia = [0x0102, 0x0103, 0xffff]
print(ia[1]) ==> 0x0103
 

Ответ №1:

Вы можете использовать int.from_bytes и небольшое понимание списка. Пожалуйста, обратите внимание, что это byte_order необходимо указать, поэтому вам, возможно, придется изменить это в зависимости от вашего приложения.

 ba = bytearray([0x01, 0x02, 0x01, 0x03, 0xff, 0xff])
ia = [int.from_bytes(ba[i:i 2], "big") for i in range(0, len(ba), 2)]
 

Комментарии:

1. Легкая адаптация к моему реальному случаю упаковки в литтл-эндиане.

Ответ №2:

Это похоже на кодировку большого конца (первый байт-старшие биты). Вы можете воспользоваться struct пакетом. Он использует строку формата для описания байтов, поступающих из некоторых итерируемых.

 import struct
unpacker = struct.Struct(">H")
ba = bytearray([0x01, 0x02, 0x01, 0x03, 0xff, 0xff])
result =  [unpacked[0] for unpacked in unpacker.iter_unpack(ba)]
print([hex(r) for r in result])
 

Полный набор спецификаторов endian приведен в порядке байтов, размере и выравнивании документов.

Комментарии:

1. Спасибо. Пример действительно был биг-эндианским, но мой реальный случай-литтл-эндианский.

2. @ysap — если вам нужен литтл-эндианский, укажите это в своем вопросе и покажите это в своем примере вывода. [0x0201, 0x0301, 0xffff]. Будущие посетители по достоинству оценят это. (опубликовал это в неправильном ответе минуту назад!).

3. Ваш ответ отвечает на заданный вопрос. Проблема конечности вторична.