Самый быстрый способ упаковать плоский c_long_Array с координатами [x1, y1, z1, ...,] в список кортежей [(x1, y2, z3), ...] - PullRequest
0 голосов
/ 21 марта 2020

У меня фиксированная длина c_long_Array (ctypes, в основном итерируемая) с координатами, сложенными слева направо. Количество координат не будет известно во время выполнения. Как только появится элемент OUT_OF_RANGE, больше не будет координат:

[x1, y1, z1, x2, y2, z2, ..., OUT_OF_RANGE_INT, OUT_OF_RANGE_INT ,OUT_OF_RANGE_INT]

Я хочу преобразовать это в список в этом формате

[(x1, y1, z1), (x2, y2, z2), ..., (xn, yn, zn)]

My текущий код выглядит следующим образом

OUT_OF_RANGE_INT = 2147483647

def parse_coordinates(raw_coordinates):
    packed_list = []
    i = 0
    while (x := raw_coordinates[i]) != OUT_OF_RANGE_INT:
        packed_list.append((x,
                            raw_coordinates[i + 1],  # y
                            raw_coordinates[i + 2])) # z
        i += 3
    return packed_list

Это узкое место в моем приложении. Как я могу улучшить скорость этой функции?

1 Ответ

0 голосов
/ 21 марта 2020

Создание такого большого списка займет время и много памяти. Если вам не нужно использовать весь список сразу, я бы предложил использовать islice и takewhile из itertools для создания функции генератора:

>>> import array
>>> from itertools import islice, takewhile
>>> def test(c):
...     it = takewhile(lambda i: i < 30, c)
...     chunk = tuple(islice(it, 3))
...     while chunk:
...         yield chunk
...         chunk = tuple(islice(it, 3))
...
>>> for i in test(array.array('l', range(100))): print(i)
... 
(0, 1, 2)
(3, 4, 5)
(6, 7, 8)
(9, 10, 11)
(12, 13, 14)
(15, 16, 17)
(18, 19, 20)
(21, 22, 23)
(24, 25, 26)
(27, 28, 29)
...