Как преобразовать часть кортежа Python (байтовый массив) в целое число - PullRequest
7 голосов
/ 22 декабря 2008

Я пытаюсь поговорить с устройством, использующим Python. Мне передали кортеж байтов, который содержит информацию о хранилище. Как я могу преобразовать данные в правильные значения:

ответ = (0, 0, 117, 143, 6)

Первые 4 значения представляют собой 32-разрядное целое число, указывающее, сколько байтов было использовано, а последнее значение - это процентное соотношение.

Я могу получить доступ к кортежу в качестве ответа [0], но не могу понять, как я могу получить первые 4 значения в требуемом int.

Ответы [ 6 ]

13 голосов
/ 22 декабря 2008

Would,

num = (ответ [0] << 24) + (ответ [1] << 16) + (ответ [2] << 8) + ответ [3] </p>

удовлетворить ваши потребности?

помощь

11 голосов
/ 22 декабря 2008

См. Преобразование байтов в числа с плавающей точкой в ​​Python

Вы, вероятно, хотите использовать модуль struct, например,

import struct

response = (0, 0, 117, 143, 6)
struct.unpack(">I", ''.join([chr(x) for x in response[:-1]]))

Предполагая неподписанный int. Может быть, есть лучший способ сделать преобразование в распакованный, понимание списка с помощью join было первым, что я придумал.

РЕДАКТИРОВАТЬ : См. Также комментарий ΤΖΩΤΖΙΟΥ к этому ответу относительно порядка байтов.

РЕДАКТИРОВАТЬ # 2 : Если вы не возражаете против использования модуля массива, вот альтернативный метод, который устраняет необходимость в понимании списка. Спасибо @ JimB за указание на то, что распаковка может работать и с массивами.

import struct
from array import array

response = (0, 0, 117, 143, 6)
bytes = array('B', response[:-1])
struct.unpack('>I', bytes)
4 голосов
/ 22 декабря 2008

Вы также можете использовать модуль массива

import struct
from array import array
response = (0, 0, 117, 143, 6)
a = array('B', response[:4])
struct.unpack('>I', a)

(30095L,)
4 голосов
/ 22 декабря 2008

ОК, Вы не указываете endinanness, не является ли целое число подписанным или и это (возможно) быстрее для модуля struct, но:

b = (8, 1, 0, 0)
sum(b[i] << (i * 8) for i in range(4))
2 голосов
/ 21 апреля 2011

Это похоже на работу по сокращению!

Что вам в основном нужно, это сдвигать бит по байтам за раз, а затем добавлять (добавлять) следующий байт в последовательности.

a = (0, 0, 117, 143, 6)
reduce(lambda x, y: (x<<8) + y, a)
7704326
0 голосов
/ 24 мая 2009

Как насчет использования функции карты:

a = (0, 0, 117, 143, 6)
b = []
map(b.append, a)

Кроме того, я не знаю, если это вы ищете:

response = (0, 0, 117, 143, 6)
response[0:4]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...