Python bytes concatenation

Try this

values = [0x49, 0x7A]
concat = (values[0] << 8) + values[1]
print(hex(concat))

you should get 0x497A


bytes is a sequence type. Its individual elements are integers. You can't do a + a[0] for the same reason you can't do a + a[0] if a is a list. You can only concatenate a sequence with another sequence.

bytes(a[0]) gives you that because a[0] is an integer, and as documented doing bytes(someInteger) gives you a sequence of that many zero bytes (e.g,, bytes(3) gives you 3 zero bytes).

{a[0]} is a set. When you do bytes({a[0]}) you convert the contents of that set into a bytes object. This is not a great way to do it in general, because sets are unordered, so if you try to do it with more than one byte in there you may not get what you expect.

The easiest way to do what you want is a + a[:1]. You could also do a + bytes([a[0]]). There is no shortcut for creating a single-element bytes object; you have to either use a slice or make a length-one sequence of that byte.


Bytes don't work quite like strings. When you index with a single value (rather than a slice), you get an integer, rather than a length-one bytes instance. In your case, a[0] is 20 (hex 0x14).

A similar issue happens with the bytes constructor. If you pass a single integer in as the argument (rather than an iterable), you get a bytes instance that consists of that many null bytes ("\x00"). This explains why bytes(a[0]) gives you twenty null bytes. The version with the curly brackets works because it creates a set (which is iterable).

To do what you want, I suggest slicing a[0:1] rather than indexing with a single value. This will give you a bytes instance that you can concatenate onto your existing value.

a += a[0:1]

If you want to change your byte sequence, you should use a bytearray. It is mutable and has the .append method:

>>> a = bytearray(b'\x14\xf6')
>>> a.append(a[0])
>>> a
bytearray(b'\x14\xf6\x14')

What happens in your approach: when you do

a += a[0]

you are trying to add an integer to a bytes object. That doesn't make sense, since you are trying to add different types.

If you do

bytes(a[0])

you get a bytes object of length 20, as the documentation describes:

If [the argument] is an integer, the array will have that size and will be initialized with null bytes.

If you use curly braces, you are creating a set, and a different option in the constructor is chosen:

If it is an iterable, it must be an iterable of integers in the range 0 <= x < 256, which are used as the initial contents of the array.

Tags:

Python 3.X