Reputation: 3265
I have a bytes
element. My word size is 1, a single byte. The contents can be b'\xff\xff\x01'
meaning [-1, -1, 1]
.
I want to convert it to the int representation from the bytes form. Logically my attempt is:
ints = [int.from_bytes(j, byteorder='little', signed=True) for j in b'\xff\xff\x01']
TypeError: cannot convert 'int' object to bytes
However this does not work as the for j in bytes()
converts a bytes element directly into an int j
. This is however an unsigned conversion, I need signed. How do I convert my bytes, byte by byte, into a signed integer.
Upvotes: 3
Views: 2095
Reputation: 209
I don't know if it still helps! I saw your comment just now :)
ints = [int.from_bytes(bytes([j]), byteorder='little', signed=True) for j in b'\xff\xff\x01']
Upvotes: 0
Reputation: 61635
Another way, using Numpy:
>>> import numpy as np
>>> np.frombuffer(b'\xff\xff\x01', dtype=np.int8)
array([-1, -1, 1], dtype=int8)
Upvotes: 1
Reputation: 61635
However this does not work as the
for j in bytes()
converts a bytes element directly into an intj
.
As you've noticed, the bytes
is already an iterable over integer values. If we have a lot of data, it would be more memory efficient to keep the bytes
as is, and convert values on demand. We can simply do the math to convert the unsigned interpretation of a byte to the corresponding signed representation:
def signed_byte(b):
return b - 256 if b >= 128 else b
And wrap the indexing process:
def get_signed(data, index):
return signed_byte(data[index])
If we want or need to do all the conversion ahead of time, that feeds directly into the list comprehension:
ints = [signed_byte(b) for b in b'\xff\xff\x01']
On the other hand, we can reframe the question: to get a bytes
object from the original data as a subsequence (like how it worked in 2.x), we can use a 1-element slice instead; or we can wrap the int
value into a new bytes
. The former will be tricky to adapt to the original code, but the latter is trivial:
ints = [int.from_bytes(bytes([b]), byteorder='little', signed=True) for b in b'\xff\xff\x01']
Upvotes: 3
Reputation: 3265
This solution is idiotic but at least it works.
data = b'\xff\xff\x01'
result = list(struct.unpack('b' * len(data), data))
Upvotes: 0