Что является правильным путем к формированию таблицы в оперативной памяти в Python с прямыми поисками для строк и столбцов.
Я думал об использовании dict dicts этот путь,
class Table(dict):
def __getitem__(self, key):
if key not in self:
self[key]={}
return dict.__getitem__(self, key)
table = Table()
table['row1']['column1'] = 'value11'
table['row1']['column2'] = 'value12'
table['row2']['column1'] = 'value21'
table['row2']['column2'] = 'value22'
>>>table
{'row1':{'column1':'value11','column2':'value12'},'row2':{'column1':'value21','column2':'value22'}}
Я испытал затруднения в поиске для значений в столбцах.
>>>'row1' in table
True
>>>'value11' in table['row1'].values()
True
Теперь, как я делаю поиск если 'column1'
имеет 'value11'
Этот метод формирующихся таблиц неправильно?
Существует ли лучший способ реализовать такие таблицы с более легкими поисками?.
Теперь, как мне выполнить поиск, если 'column1' имеет 'value11'
any (arow ['column1'] == 'value11' для строки в table.iteritems ())
Неправильно ли этот метод формирования таблиц ?
Нет, он просто очень "открыт", возможно, слишком сильно - его можно было бы с пользой инкапсулировать в класс, предоставляющий нужные вам методы, тогда вопрос о том, как Лучше всего их реализовать не повлияет на все остальное ваше приложение.
Есть ли лучший способ реализовать такие таблицы с более простым поиском?
После того, как вы создали класс, интерфейс которого вы хотели бы использовать, вы можете поэкспериментировать с очень различные подходы к реализации и сравните их с рабочей нагрузкой, которая представляет ваш шаблон использования, чтобы вы могли выяснить, что лучше для вас (при условии, что манипуляции с таблицами и поиск являются большой частью вашего приложения время выполнения, конечно - чтобы узнать, профиль ваше приложение).
У меня были аналогичные, но не идентичные потребности в большом внутреннем приложении, которое я поддерживаю на работе, за исключением того, что индексы строк являются целыми числами (только имена столбцов являются строками), порядок столбцов важен, а рабочая нагрузка больше связана с «редактированием» "таблица (добавление, удаление, изменение порядка строк или столбцов, переименование столбцов и т. д.).Я начал с таблицы, раскрывающей нужную мне функциональность, с простейшей грубой внутренней реализации (список dicts плюс список имен столбцов для упорядочивания столбцов); и к настоящему времени я развил его (независимо от фактических частей «уровня приложения», но на основе их профилирования и тестирования производительности) до совершенно разных реализаций (в настоящее время основанных на numpy
).
Я думаю, вам следует действовать в том же духе: «облеките» вашу текущую реализацию в красивый «интерфейс» со всеми необходимыми методами, профилируйте свое приложение - если этот объект таблицы не является узким местом производительности, все готово; если это является узким местом, вы можете оптимизировать реализацию (поэкспериментировать, измерить, повторить ;-), не мешая остальным частям вашего приложения.
Наследование от dict
не является хорошей идеей, потому что вы, вероятно, не хотите раскрывать всю богатую функциональность dict
; плюс, то, что вы делаете, грубо говоря, является неэффективной реализацией collections.defaultdict (dict)
. Итак, инкапсулируйте последнее:
import collections
class Table(object):
def __init__(self):
self.d = collections.defaultdict(dict)
def add(self, row, col, val):
self.d[row][col] = val
def get(self, row, col, default=None):
return self.d[row].get(col, default)
def inrow(self, row, col):
return col in self.d[row]
def incol(self, col, val):
return any(x[col]==val for x in self.d.iteritems())
и т. Д. И т. Д. - напишите все методы, которые нужны вашему приложению, с полезными короткими именами, а затем, возможно, посмотрите, можете ли вы присвоить некоторым из них псевдонимы как специальные методы, если они ' re часто используется таким образом, например, возможно (при условии, что Python 2. * - требует немного другого синтаксиса в 3. *):
def __setitem__(self, (row, col), val):
self.add(row, col, val)
и так далее. Когда у вас работает код , затем , наступает подходящее время для профилирования, тестирования и, возможно, внутренней оптимизации реализации.
Вложенный список должен уметь выполнять здесь эту работу. Я бы использовал вложенные словари только в том случае, если элементы рассредоточены по сетке.
grid = []
for row in height:
grid.append([])
for cell in width:
grid[-1].append(value)
Проверить строки легко:
def valueInRow(value, row):
return value in grid[row]
Проверка столбцов требует немного больше работы, потому что сетка представляет собой список строк, а не список столбцов:
def collumnIterator(collumn):
height = len(grid)
for row in xrange(height):
yield grid[row][collumn]
def valueInCollumn(value, collumn):
return value in collumnIterator(collumn)
Как мне выполнить поиск, если в столбце 1 указано значение 11
Вы спрашиваете об этом?
found= False
for r in table:
if table[r]['column1'] == 'value11'
found= True
break
Это то, что вы пытаетесь сделать?
Я бы использовал для этого базу данных в памяти с SQLite . Модуль sqlite находится даже в стандартной библиотеке, начиная с Python 2.5, а это значит, что это даже не добавляет к вашим требованиям.