9

I'm trying to insert one byte array into another at the beginning. Here's a simple example of what I'm trying to accomplish.

import struct
a = bytearray(struct.pack(">i", 1))
b = bytearray(struct.pack(">i", 2))
a = a.insert(0, b)
print(a)

However this fails with the following error:

a = a.insert(0, b) TypeError: an integer is required

Russell
  • 3,384
  • 4
  • 31
  • 45

3 Answers3

14

bytearray is a sequence-type, and it supports slice-based operations. The "insert at position i" idiom with slices goes like this x[i:i] = <a compatible sequence>. So, for the fist position:

>>> a
bytearray(b'\x00\x00\x00\x01')
>>> b
bytearray(b'\x00\x00\x00\x02')
>>> a[0:0] = b
>>> a
bytearray(b'\x00\x00\x00\x02\x00\x00\x00\x01')

For the third position:

>>> a
bytearray(b'\x00\x00\x00\x01')
>>> b
bytearray(b'\x00\x00\x00\x02')
>>> a[2:2] = b
>>> a
bytearray(b'\x00\x00\x00\x00\x00\x02\x00\x01')

Note, this isn't equivalent to .insert, because for sequences, .insert inserts the entire object as the ith element. So, consider the following simple example with lists:

>>> y = ['a','b']
>>> x.insert(0, y)
>>>
>>> x
[['a', 'b'], 1, 2, 3]

What you really wanted was:

>>> x
[1, 2, 3]
>>> y
['a', 'b']
>>> x[0:0] = y
>>> x
['a', 'b', 1, 2, 3]
juanpa.arrivillaga
  • 88,713
  • 10
  • 131
  • 172
  • 2
    @Russell because `.insert` tries to *insert the object, i.e. the entire bytearray* as the ith element. But that isn't what you want, bytearrays can only contain *bytes*, not bytearray-objects. Think of this: `x = [1,2,3]; y = ['a','b']; x.insert(0,y)` will give you `x == [['a', 'b'], 1, 2, 3]` – juanpa.arrivillaga Sep 20 '17 at 20:45
1
>>> a = bytearray(struct.pack(">i", 1))
>>> b = bytearray(struct.pack(">i", 2))
>>> a = b + a
>>> a
bytearray(b'\x00\x00\x00\x02\x00\x00\x00\x01')
ezod
  • 7,261
  • 2
  • 24
  • 34
  • 1
    Yes... but I actually need to insert occasionally at a non-zero index where concatenation might not work. – Russell Sep 20 '17 at 20:34
1

Bytearray are mutable sequence of single bytes (integers), so bytearray only accepts integers that meet the value restriction 0 <= x <= 255):

>>> a = bytearray(struct.pack(">i", 1))
>>> b = bytearray(struct.pack(">i", 2))
>>> a.insert(0,b)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: an integer is required

>>> a=b+a
>>> a
bytearray(b'\x00\x00\x00\x02\x00\x00\x00\x01')

>>>a[:2]=b
>>> a
bytearray(b'\x00\x00\x00\x02\x00\x01')
  • I couldn't understand why `a[:2]=b` was giving the result `bytearray(b'\x00\x00\x00\x02\x00\x01')` for `a`. Indeed if executed after `a=b+a` the result will be `bytearray(b'\x00\x00\x00\x02\x00\x02\x00\x00\x00\x01')`. This example is not a sequence! – Toady Oct 09 '20 at 10:04