1

I have an array that i need to pack with python to 16bit depth with

I have been doing this with php without any issues. Array is just just large set of numbers like this - [1, 2, 3, 4, 5, 700, 540...] With php I do this process in one line:

$encoded_string = pack("s*", ...$array); // Done

I can not for the love of god figure out how same can be done in python I have read the documentation, I looked at examples and I can not get this done Best I have is below and it does not work in any variation i have tried.

encoded_string = struct.pack('h', *array)
azro
  • 53,056
  • 7
  • 34
  • 70
Proper
  • 155
  • 2
  • 11
  • I am also php developer working recently with python, welcome to the club. You can try to program the function or find an alternative, anyway, look [here](https://stackoverflow.com/questions/13892734/python-equivalent-of-php-pack) for some information – Anatoliy R Nov 05 '19 at 20:54
  • I feel like python puts too much of what happens outside the code structure. I end up feeling like I have no clue where things are and I am very spacial in terms on how code is structured. – Proper Nov 05 '19 at 21:50
  • Well, I started coding python because of my interest in machine learning, so I have no choice. But believe it or not, I find it really good scripting language, just requiring some practice for those who "think" in php, c/c++, java or any similar language. Of course you cannot find there some good stuff you use under php, but still it make sense to add it in the list of languages you're comfortable with – Anatoliy R Nov 05 '19 at 22:16
  • I had to do the same as well, I just do not like allot of how it works. For example instead of me taking parts of code I like, I have to import entire library and just the import takes 300ms before script runs. One line that says import X can slow down your script my seconds. Obviously there must be solution, but its a massive flaw by default. I have scripts that run 10ms in php and take 700ms in python, that is just crazy – Proper Nov 06 '19 at 01:27

2 Answers2

1

You have to call struct.pack on each member of your array:

import struct

nums = [1, 2, 3, 4, 5, 700, 540]
as_bytes = [struct.pack('h', i) for i in nums]

# Produces
[b'\x01\x00', b'\x02\x00', b'\x03\x00', b'\x04\x00', b'\x05\x00', b'\xbc\x02', b'\x1c\x02', b'\x08\x00']

and then that you can join into a single byte string if you want:

>>> b''.join(as_bytes)
b'\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\xbc\x02\x1c\x02'

Note: you can also use the endianness modifiers to specify the alignment for the output bytes.

Edit: @Proper reminded me that struct.pack's formatting also supports specifying the number of target packed types, so this can be done more easily by including the data length in an f-string with the format specifier:

>>> struct.pack(f'{len(data)}h', *data)
b'\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\xbc\x02\x1c\x02'
b_c
  • 1,202
  • 13
  • 24
1

Thank you for the reply b_c to be honest I hate python with a passion at this point, there was another problem that i had to fix, the array was created as str and not int after it was "exploded". So it had to be remapped to int.

Your code does work, thank you. There is a way to do it with my initial code, however you have to define number of values you want to process. It is possible to simply count number of values in the array and add than in to make it automated

data_array  = map(int,data)   # converts all values in the array to int
encoded_string = struct.pack('240s',*data_array) # 240 is number of values in the array
Proper
  • 155
  • 2
  • 11
  • Good call! I'll update my answer to include the number, I forgot all about that. – b_c Nov 05 '19 at 21:26