bytes is immutable. Use bytearray.
xs = bytearray(b'\x01\x02\x03')
xs.append(5)
Answer from simonzack on Stack Overflowbytes is immutable. Use bytearray.
xs = bytearray(b'\x01\x02\x03')
xs.append(5)
First of all passing an integer(say n) to bytes() simply returns an bytes string of n length with null bytes. So, that's not what you want here:
Either you can do:
>>> bytes([5]) #This will work only for range 0-256.
b'\x05'
Or:
>>> bytes(chr(5), 'ascii')
b'\x05'
As @simonzack already mentioned, bytes are immutable, so to update (or better say re-assign) its value, you need to use the += operator.
>>> s = b'\x01\x02\x03'
>>> s += bytes([5]) #or s = s + bytes([5])
>>> s
b'\x01\x02\x03\x05'
>>> s = b'\x01\x02\x03'
>>> s += bytes(chr(5), 'ascii') ##or s = s + bytes(chr(5), 'ascii')
>>> s
b'\x01\x02\x03\x05'
Help on bytes():
>>> print(bytes.__doc__)
bytes(iterable_of_ints) -> bytes
bytes(string, encoding[, errors]) -> bytes
bytes(bytes_or_buffer) -> immutable copy of bytes_or_buffer
bytes(int) -> bytes object of size given by the parameter initialized with null bytes
bytes() -> empty bytes object
Construct an immutable array of bytes from:
- an iterable yielding integers in range(256)
- a text string encoded using the specified encoding
- any object implementing the buffer API.
- an integer
Or go for the mutable bytearray if you need a mutable object and you're only concerned with the integers in range 0-256.
I'm trying to add elements from one bytearray to another. This is the source bytearray:
filedata = open("file.bin", "rb").read()
fileba = bytearray(filedata)This is the new bytearray to be built-up from scratch:
newba = bytearray()
The problem is when I try to copy byte elements from the old to the new :
for baelement in fileba
newba += b'\xC0' #This works fine!
newba += fileba [0] #Doesn't work - "can't concat int to bytearray"
newba += baelement #Doesn't work - "can't concat int to bytearray"
newba.extend (baelement ) #Doesn't work - "'int' object is not iterable"I'm using Python 2.7.6, but can't get it to copy bytes from one bytearray to the other.. what could be the problem?
You don't need the loop, just do
newba += fileba
Or am I missing something?
newba += fileba [0] should be newba.append(fileba[0])
newba += baelement should be newba.append(baelement)
This is because += and .extend() expect iterables.
bytearray[x] returns an int object which is not iterable -- unless x is a slice, like [0:10], in which case another bytearray is returned.
for x in bytearray also returns int objects for x.
.append, however, will accept a non-iterable object -- in fact, .append throws if not passed an integer or string of size 1
TypeError: an integer or string of size 1 is required
.extend and += work for an iterable, though, like newba.extend(fileba[0:10]) or newba += fileba[0:10]
newba += b'\xC0' works because a str object is iterable, even if only a single character in length.
EDIT: s/length/size/
Append bytes
Python 3 Building an array of bytes - Stack Overflow
arrays - How to add bytes to bytearray in Python 3.7? - Stack Overflow
How to append two bytes in python? - Stack Overflow
Use a bytearray:
>>> frame = bytearray()
>>> frame.append(0xA2)
>>> frame.append(0x01)
>>> frame.append(0x02)
>>> frame.append(0x03)
>>> frame.append(0x04)
>>> frame
bytearray(b'\xa2\x01\x02\x03\x04')
or, using your code but fixing the errors:
frame = b""
frame += b'\xA2'
frame += b'\x01'
frame += b'\x02'
frame += b'\x03'
frame += b'\x04'
what about simply constructing your frame from a standard list ?
frame = bytes([0xA2,0x01,0x02,0x03,0x04])
the bytes() constructor can build a byte frame from an iterable containing int values. an iterable is anything which implements the iterator protocol: an list, an iterator, an iterable object like what is returned by range()...
packet_bytes += bytearray(current_bytes)
I recently had this problem myself and this is what worked for me. Instead of instantiating a bytearray, I just initialized my buffer as a byte object:
buf = b"" #Initialize byte object
poll = uselect.poll()
poll.register(uart, uselect.POLLIN)
while True:
ch = uart.read(1) if poll.poll() else None
if ch == b'x':
buf += ch #append the byte character to the buffer
if ch == b'y':
buf = buf[:-1] #remove the last byte character from the buffer
if ch == b'\015': ENTER
break
Byte strings (and Unicode strings) in Python are immutable, whereas lists are mutable.
What this means is that every append (+=) done on a byte string must make a copy of that string; the original is not modified (though it will be garbage-collected later). In contrast, the append method of list (also used by +=) will actually modify the list.
What you want is the bytearray type, which is a mutable type functioning much like a list of bytes. Appending to a bytearray takes (amortized) constant time, and it is easily converted to and from a byte string.
A bytes object is immutable just like a string. Every time you do a += something, Python is creating a new object, copying a + something into it, and then assigning it to a.
You will be better using the bytearray type which is a mutable sequence and supports an append method.