Resetting bytearray

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
danielm
Posts: 167
Joined: Mon Oct 05, 2015 12:24 pm

Resetting bytearray

Post by danielm » Wed Oct 05, 2016 9:53 am

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.

User avatar
deshipu
Posts: 1388
Joined: Thu May 28, 2015 5:54 pm

Re: Resetting bytearray

Post by deshipu » Wed Oct 05, 2016 10:34 am

The obvious solution would be:

Code: Select all

for i in range(len(your_array)):
    your_array[i] = 0

User avatar
platforma
Posts: 258
Joined: Thu May 28, 2015 5:08 pm
Location: Japan

Re: Resetting bytearray

Post by platforma » Wed Oct 05, 2016 11:12 am

One more option is

Code: Select all

arr[:] = b'0' * len(arr)

User avatar
kfricke
Posts: 342
Joined: Mon May 05, 2014 9:13 am
Location: Germany

Re: Resetting bytearray

Post by kfricke » Wed Oct 05, 2016 12:01 pm

platforma wrote:One more option is

Code: Select all

arr[:] = b'0' * len(arr)
Does this really not re-allocate the buffer?

User avatar
platforma
Posts: 258
Joined: Thu May 28, 2015 5:08 pm
Location: Japan

Re: Resetting bytearray

Post by platforma » Wed Oct 05, 2016 12:13 pm

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

User avatar
deshipu
Posts: 1388
Joined: Thu May 28, 2015 5:54 pm

Re: Resetting bytearray

Post by deshipu » Wed Oct 05, 2016 12:23 pm

It allocates a new buffer, and then copies it over to the old one.

User avatar
deshipu
Posts: 1388
Joined: Thu May 28, 2015 5:54 pm

Re: Resetting bytearray

Post by deshipu » Wed Oct 05, 2016 12:26 pm

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

markxr
Posts: 62
Joined: Wed Jun 01, 2016 3:41 pm

Re: Resetting bytearray

Post by markxr » Wed Oct 05, 2016 1:00 pm

I used:

Code: Select all

tempbuf = bytearray() 

# ...

tempbuf[::] = b''
Is that ok, or not?

User avatar
deshipu
Posts: 1388
Joined: Thu May 28, 2015 5:54 pm

Re: Resetting bytearray

Post by deshipu » Wed Oct 05, 2016 1:47 pm

No, that truncates the array to make it 0-element long.

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Resetting bytearray

Post by pythoncoder » Fri Oct 07, 2016 9:57 am

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.
Peter Hinch
Index to my micropython libraries.

Post Reply