python - Splitting a byte list into a list of dicts -


i have byte data (say image):

00 19 01 21 09 0f 01 15 .. ff

i parse , store byte list:

[b'\x00', b'\x19', b'\x01', b'\x21', b'\x09', b'\x0f', b'\x01', b'\x15', ...]

these rgba values (little endian, 2 bytes) need parse dict format follows:

[{'red':0x0019, 'green':0x2101, 'blue':0x0f09, 'alpha':0x1501}, {'red':...},...]

note: image data terminates once reach 0xff. values can stored in hex or decimal, doesn't matter long it's consistent.

my attempt:

# our dict keys keys = ['red', 'green', 'blue', 'alpha']  # first, grab bytes until hit 0xff img = list(takewhile(lambda x: x != b'\xff', bitstream))  # traverse img 2 bytes @ time , join them rgba = [] i,j in zip(img[0::2],img[1::2]):   rgba.append(b''.join([j,i]) # j first since byteorder 'little' 

so far output [0x0019, 0x2101, 0x0f09, ...]

now i'm stuck on how create list of dicts "pythonically". can use loop , pop 4 items list @ time that's not using python's features potential. advice?

note: example, keys can (not related images). overlook issues len(img) % len(keys) != 0.

first, use stringio create file-like object bitstream facilitate grabbing 8-byte chunks 1 @ time. then, use struct.unpack convert each 8-byte chunk tuple of 4 integers, zip tuple of keys create list can passed directly dict. wrapped in list comprehension create rgba in 1 pass.

(i use functools.partial , itertools.imap improve readabililty.)

import stringio import re itertools import imap functools import partial  keys = ("red", "green", "blue", "alpha") # create object can read str_iter = stringio.stringio(re.sub("\xff.*", "", bitstream)) # callable reads 8 bytes @ time str_iter read_8_bytes = partial(str_iter.read, 8) # convert 8-byte string tuple of 4 integer values unpack_rgba = partial(struct.unpack, "<hhhh") # iterable of 8-byte strings chunk_iter = iter(read_8_bytes, '') # map unpack_rgba on iterator iterator of 4-tuples, # zip each 4-tuple key tuple create desired dict rgba = [dict(zip(keys, rgba_values))          rgba_values in imap(unpack_rgba, chunk_iter)] 

(if getting binary data like

with open('somefile', 'rb') fh:     bitstream = fh.read() 

then can use file iterator in place of str_iter, read bytes file need them, rather @ once.)


Comments

Popular posts from this blog

android - MPAndroidChart - How to add Annotations or images to the chart -

javascript - Add class to another page attribute using URL id - Jquery -

firefox - Where is 'webgl.osmesalib' parameter? -