Найти - Пользователи
Полная версия: Матрица-таблица
Начало » Python для новичков » Матрица-таблица
1
Kogrom
Сочиняю матрицу для хранения данных, которые буду выводить на график. Подозреваю, что изобретаю велосипед, но пока альтернативы не нашел. Выкладываю то, что сделал.

ТЗ на таблицу.

Создать двумерную прямоугольную матрицу-таблицу для хранения однотипных простых данных. Данные в таблице не редактируются, но могут дополняться путем добавления столбцов или строк. При любом добавлении таблица должны сохранять прямоугольную форму: все строки остаются одинаковой длины и все столбцы также.

Должны быть предусмотрены методы чтения строк и столбцов. При этом необходимо закрыть методы редактирования столбцов и строк.

Строки в таблицу добавляются часто. Их может быть до нескольких сотен тысяч. Столбцов в среднем от пяти до десяти, максимум - не более пятисот. Столбцы добавляются намного реже, чем строки. Но читаться будут в основном только столбцы. Более того, основная задача внешних объектов - читать столбцы.

Дополнение к следующей версии: предусмотреть удаление строк и столбцов, автоудаление старых строк, при достижении определенного лимита.

Анализ:

Так как столбцы будут читаться чаще всего, то выгоднее их поместить в более низкоуровневый контейнер, типа 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)
Если кто-то знает альтернативы, то прошу подсказать. Если не знает, но видит ошибки в моем тексте и коде, то тоже буду рад критике.
Ferroman
Сочиняю матрицу для хранения данных, которые буду выводить на график. Подозреваю, что изобретаю велосипед, но пока альтернативы не нашел.
Numpy
Kogrom
Ferroman
Numpy
Я и сам изучил основные приёмы работы с матрицами Numpy. Но насколько я понял, они заточены на быструю обработку матриц. Мне же надо добавление строк и столбцов и неизменяющее чтение. Сложной обработки почти не надо.

Я нашел функции reshape, resize, но с их помощью неудобно добавлять строки и столбцы, и, вероятно, не совсем эффективно. А метода передачи константной ссылки на столбец я вообще не нашёл. То есть Вид из MVC сможет менять значения, которые не должен трогать.

Возможно, Ferroman невнимательно прочитал о том, что мне надо. Прошу уточнить, если я что-то неправильно понимаю.
Ferroman
Всё верно, всё именно так и есть.
Правда, по поводу скорости я не уверен, и не думаю что скорость будет сильно различна. Но это умозрительно, и надо проверять профайлером.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB