views:

99

answers:

2

I'm having trouble understanding the result of the following statements:

>>> from array import array
>>> array('L',[0xff,0xff,0xff,0xff])
array('L', [255L, 255L, 255L, 255L])


>>> from array import array
>>> array('L','\xff\xff\xff\xff')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: string length not a multiple of item size
+3  A: 

You are running this on a 64-bit build of Python, on which array treats type code 'L' as a 64-bit unsigned integer.

>>> array('L','\xff\xff\xff\xff\xff\xff\xff\xff')
array('L', [18446744073709551615L])

The documentation isn't very clear. All it says is that 'L' is at least four bytes.

Marcelo Cantos
Yes, I think this is the issue ... I changed to 'I' and it work. A cursory glance of the document does not make this clear.
Casey
+1  A: 

In the first case you are initializing the array from a list with 4 elements. That will give you an array with 4 elements: one for each value in the list.

In the second case you are initializing the array from a byte string: the bytes in the string will be copied directly into the array. The 'L' specifier creates an array of unsigned longs which have a minimum size of 4 bytes.

On my machine (Windows 64 bit Python 2.6) initializing from a 4 byte string works fine:

>>> a = array('L','\xff\xff\xff\xff')

>>> a.tostring()
'\xff\xff\xff\xff'

I guess whichever version of Python you are using has unsigned longs that are 8 bytes rather than 4. Try converting the array you created from a list back to a string and see how many bytes that contains:

>>> a = array('L',[0xff,0xff,0xff,0xff])
>>> a.tostring()
'\xff\x00\x00\x00\xff\x00\x00\x00\xff\x00\x00\x00\xff\x00\x00\x00'

P.S. I'm assuming that you are using Python 2.x, on Python 3.x you would have got a TypeError instead.

Duncan