This code works perfectly:
b'\x4a' b'\x20'
b'J '
But this doesn't:
sum([b'\x4a', b'\x20'])
TypeError: unsupported operand type(s) for : 'int' and 'bytes'
Why? How to concatenate many bytes
elements?
CodePudding user response:
You can use join
instead:
b''.join([b'\x4a', b'\x20'])
Output:
b'J '
CodePudding user response:
If you actually had no choice but to use sum
, this is one way you could do it. This iterates over the bytes
, converting them to ints
and bit-shifting each one to the next byte
. Then it sums
all of those ints
and coverts the sum
back to bytes
.
This isn't meant to be the "best" answer. It's the "how to do it with sum" answer. You probably shouldn't use this. It's a little bit clever, because it stores the byte length as it goes, and is therefore never wrong or needing a final equation to determine it (as long as your list
is of single bytes
).
from typing import Iterable
def sum_concat_bytelist(bl:Iterable, e:str='little') -> bytes:
return sum(int.from_bytes(b,e)<<((l:=i)<<3) for i,b in enumerate(bl)).to_bytes(l 1,e)
If you wanted to be able to use bytes
of any length at each list
index, you have to make some modifications. This version eliminates enumerate
and manages the i
manually.
from typing import Iterable
def sum_concat_bytelist(bl:Iterable, e:str='little') -> bytes:
i, l = 0, lambda n,i: (((n.bit_length() 7)//8)<<3) i #total current bits forced to multiples of 8
# use last `i`---v v---store next `i`
return sum((n:=int.from_bytes(b,e))<<(i,i:=l(n,i))[0] for b in bl).to_bytes((i 7)//8,e)
print(sum_concat_bytelist([b'\x20\x4a',b'\x4a\x20']))
Both of these ways are probably about as good as it's going to get for what they are, but at best, I would consider this just an experiment. Using .join
is the way to go.