# In Python Fast Way To Convert A Bytearray To Array Of Tuples (Without Using NumPy)

## 26 April 2019 - 1 answer

I need to speed up the following code:-

``````index = 0
WIDTH = 1920
HEIGHT = 1080
for o in xrange(WIDTH * HEIGHT):
outbuf[o] = (buffer[index], buffer[index+1], buffer[index+2])
index += 3
``````

Which converts a bytearray to an array of tuples, but is too slow, is there any way to make it faster without using numpy.

Building `outbuf` using the grouper recipe from `itertools` is almost twice as fast on my machine.

This is the grouper function from the docs:

``````def grouper(iterable, n, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)
``````

This script compares timings for the function in the question, using grouper to populate outbuf and using grouper to return outbuf rather than populating an external list. The fastest method is to return `outbuf` from the function.

``````from itertools import izip_longest
import random
import sys
import timeit

WIDTH = 1920
HEIGHT = 1080

buffer_ = bytearray(random.randint(0, 255) for _ in xrange(WIDTH * HEIGHT * 3))

# Function from the question
def extract(buffer_):
index = 0
for o in xrange(WIDTH * HEIGHT):
outbuf[o] = (buffer_[index], buffer_[index+1], buffer_[index+2])
index += 3

def grouper(iterable, n, fillvalue=None):
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)

# Use grouper with external outbuf
def grouper_extract(buffer_):
groups = grouper(buffer_, 3)
for o in xrange(WIDTH * HEIGHT):
outbuf[o] = next(groups)

# Return a list using grouper
def grouper_list(buffer_):
return list(grouper(buffer_, 3))

if __name__ == '__main__':
# Set number of timeit repetitions.
try:
number = int(sys.argv[1])
except IndexError:
number = 50
outbuf = [0 for _ in xrange(WIDTH * HEIGHT * 3)]
print 'OP function'
print timeit.timeit(setup="from __main__ import extract, outbuf, buffer_",
stmt="extract(buffer_)", number=number)
print
print 'Fill external outbuf with grouper'
print timeit.timeit(setup="from __main__ import grouper_extract, outbuf, buffer_",
stmt="grouper_extract(buffer_)", number=number)
print
print 'Return outbuf using grouper'
print timeit.timeit(setup="from __main__ import grouper_list, buffer_",
stmt="outbuf = grouper_list(buffer_)", number=number)
print
``````

Here are the timings for 50 repetitions of each approach:

``````OP function
39.3345730305

Fill external outbuf with grouper
30.0249710083

Return outbuf using grouper
20.357350111
``````