34

I want to concatenate the first byte of a bytes string to the end of the string:

a = b'\x14\xf6'
a += a[0]

I get an error:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't concat bytes to int

When I type bytes(a[0]) I get:

b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

And bytes({a[0]}) gives the correct b'\x14'.

Why do I need {} ?

3
  • 1
    What are you trying to achieve? Commented Jan 24, 2015 at 22:03
  • Could You see my post: [stackoverflow.com/questions/54682735/… ? I have problem with concatenate bytes. Each run of my script gives different results. Commented Feb 14, 2019 at 18:35
  • @jasper, it should not matter. In its pure form this is good question. Its a problem many intermediate Python programmers, or those coming from other languages might face. Commented Sep 17, 2023 at 23:13

4 Answers 4

26

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]
Sign up to request clarification or add additional context in comments.

Comments

23

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.

Comments

8

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.

Comments

1

Try this

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

you should get 0x497A

2 Comments

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
While this works adding bytes in this way will result in python having to add absurdly large numbers for anything other than very short bytes strings

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.