Форум сайта python.su
Сочиняю матрицу для хранения данных, которые буду выводить на график. Подозреваю, что изобретаю велосипед, но пока альтернативы не нашел. Выкладываю то, что сделал.
ТЗ на таблицу.
Создать двумерную прямоугольную матрицу-таблицу для хранения однотипных простых данных. Данные в таблице не редактируются, но могут дополняться путем добавления столбцов или строк. При любом добавлении таблица должны сохранять прямоугольную форму: все строки остаются одинаковой длины и все столбцы также.
Должны быть предусмотрены методы чтения строк и столбцов. При этом необходимо закрыть методы редактирования столбцов и строк.
Строки в таблицу добавляются часто. Их может быть до нескольких сотен тысяч. Столбцов в среднем от пяти до десяти, максимум - не более пятисот. Столбцы добавляются намного реже, чем строки. Но читаться будут в основном только столбцы. Более того, основная задача внешних объектов - читать столбцы.
Дополнение к следующей версии: предусмотреть удаление строк и столбцов, автоудаление старых строк, при достижении определенного лимита.
Анализ:
Так как столбцы будут читаться чаще всего, то выгоднее их поместить в более низкоуровневый контейнер, типа list или array.array. Второй контейнер даже предпочтительнее. Если строки хранить в подобных контейнерах, тогда упростится добавление строк, но усложнится чтение и анализ столбцов.
Для ограничения чтения можно использовать 3 метода: хранить данные в константных контейнерах типа tuple, копировать данные, передавать обёртку, закрывающую методы редактирования. Для строк будем использовать копирование, чтобы не передавать ссылку на всю таблицу, для столбцов - обёртки, так как большие столбцы часто копировать неэффективно.
Черновой код:
class ArrayCover():
def __init__(self, list_):
self.__list = list_
def __getitem__(self, index):
return self.__list[index]
def __str__(self):
return str(list(self.__list))
class RectMatrix:
def __init__(self, type_):
self.__matrix = []
self.__colLength = 0
self.__type = type_
def __repr__(self): # basic purpose of this function is testing
res = ''
for i in xrange(self.__colLength):
res += repr(self.get_row(i)) + '\n'
return res
def add_column(self, column):
if not len(column): return
if len(self.__matrix):
self.__matrix.append(column[:self.__colLength])
if len(self.__matrix[-1]) < self.__colLength:
self.__matrix[-1].extend(
[self.__matrix[-1][-1]]*(self.__colLength - len(self.__matrix[-1])))
else:
self.__matrix.append(column)
self.__colLength = len(column)
def add_row(self, row):
if not len(row): return
if len(self.__matrix):
for i, col in enumerate(self.__matrix):
if i < len(row):
col.append(row[i])
else:
col.append(0)
else:
import array
self.__matrix = [array.array(self.__type, [data]) for data in row]
self.__colLength += 1
def get_row(self, index = -1):
if index < self.__colLength and self.__colLength:
return [col[index] for col in self.__matrix]
def get_column(self, index):
if index < len(self.__matrix) and len(self.__matrix):
return ArrayCover(self.__matrix[index])
def get_column_length(self):
return self.__colLength
def get_row_length(self):
return len(self.__matrix)
Офлайн
Сочиняю матрицу для хранения данных, которые буду выводить на график. Подозреваю, что изобретаю велосипед, но пока альтернативы не нашел.Numpy
Офлайн
FerromanЯ и сам изучил основные приёмы работы с матрицами Numpy. Но насколько я понял, они заточены на быструю обработку матриц. Мне же надо добавление строк и столбцов и неизменяющее чтение. Сложной обработки почти не надо.
Numpy
Офлайн
Всё верно, всё именно так и есть.
Правда, по поводу скорости я не уверен, и не думаю что скорость будет сильно различна. Но это умозрительно, и надо проверять профайлером.
Офлайн