Page 1 of 2
Resetting bytearray
Posted: Wed Oct 05, 2016 9:53 am
by danielm
How to "reset" bytearray (set all bytes to b'\x00') without being re-allocated?
After doing this function id() should return same value as before.
Re: Resetting bytearray
Posted: Wed Oct 05, 2016 10:34 am
by deshipu
The obvious solution would be:
Code: Select all
for i in range(len(your_array)):
your_array[i] = 0
Re: Resetting bytearray
Posted: Wed Oct 05, 2016 11:12 am
by platforma
Re: Resetting bytearray
Posted: Wed Oct 05, 2016 12:01 pm
by kfricke
platforma wrote:One more option is
Does this really not re-allocate the buffer?
Re: Resetting bytearray
Posted: Wed Oct 05, 2016 12:13 pm
by platforma
At least not from what I tried on unix port:
Code: Select all
>>> arr = bytearray([1,2,3])
>>> arr
bytearray(b'\x01\x02\x03')
>>> id(arr)
140355047877312
>>> arr[:] = b'0' * len(arr)
>>> arr
bytearray(b'000')
>>> id(arr)
140355047877312
Re: Resetting bytearray
Posted: Wed Oct 05, 2016 12:23 pm
by deshipu
It allocates a new buffer, and then copies it over to the old one.
Re: Resetting bytearray
Posted: Wed Oct 05, 2016 12:26 pm
by deshipu
The below code could be much more memory-efficient, unfortunately it's not working:
Code: Select all
>>> a[:] = (b'0' for i in range(10))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NotImplementedError: array/bytes required on right side
Re: Resetting bytearray
Posted: Wed Oct 05, 2016 1:00 pm
by markxr
I used:
Code: Select all
tempbuf = bytearray()
# ...
tempbuf[::] = b''
Is that ok, or not?
Re: Resetting bytearray
Posted: Wed Oct 05, 2016 1:47 pm
by deshipu
No, that truncates the array to make it 0-element long.
Re: Resetting bytearray
Posted: Fri Oct 07, 2016 9:57 am
by pythoncoder
Code: Select all
$ ./upython
MicroPython v1.8.1-39-gdb4addd on 2016-07-01; linux version
Use Ctrl-D to exit, Ctrl-E for paste mode
>>> a = bytearray(10)
>>> id(a)
139728051341376
>>> a[:] = b'\1' * len(a)
>>> id(a)
139728051341376
>>> a
bytearray(b'\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01')
>>> a[:] = b'\0' * len(a)
>>> a
bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
>>> id(a)
139728051341376
>>>
While this preserves the ID, I assume a bytes object is temporarily allocated before being copied to the original. Aside from the original suggestion from @deshipu I can see two ways to avoid allocation. One, if speed is critical, would be to implement the original solution using inline assembler. The other would be to define a bytes instance for copying and freeze it as bytecode.