On Wednesday 25 March 2015 14:13, otaksoftspamt...@gmail.com wrote: > I have a list containing 9600 integer elements - each integer is either 0 > or 1. > > Starting at the front of the list, I need to combine 8 list elements into > 1 by treating them as if they were bits of one byte with 1 and 0 denoting > bit on/off (the 8th element would be the rightmost bit of the first byte). > > The end result should be a new list that is 8 x shorter than the original > list containing integers between 0 and 255. > > Speed is not of utmost importance - an elegant solution is. Any > suggestions?
Collate the list into groups of 8. Here, I pad the list with zeroes at the end. If you prefer to drop any excess bits instead of padding them, use itertools.izip instead of izip_longest. import itertools mylist = [1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1] grouped = itertools.izip_longest(*([iter(mylist)]*8), fillvalue=0) Now convert each group of eight into a byte: def byte(bits): n = 0 for b in bits: assert b in (0, 1) n = n*2 + b return n [byte(x) for x in grouped] Or if you prefer using built-ins: [int(''.join(str(b) for b in x), 2) for x in grouped] I have no idea which will be faster. Exercise for the reader: izip will drop any bits that don't make up an octet. izip_longest will pad with zeroes on the least-significant side, e.g. [1, 1] -> 192. How to pad on the most-significant side, or equivalently, don't pad at all, so that [1, 1] -> 3? -- Steve -- https://mail.python.org/mailman/listinfo/python-list