Таблица Python In-memory - PullRequest
       18

Таблица Python In-memory

4 голосов
/ 02 апреля 2010

Как правильно формировать таблицу в памяти на python с прямым поиском строк и столбцов.
Я думал об использовании dict of 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'
Является ли этот метод формирования таблиц неправильным?
Есть ли лучший способ реализовать такие таблицы с более легкими поисками?.

Ответы [ 4 ]

7 голосов
/ 02 апреля 2010

Теперь, как мне сделать поиск, если 'column1' имеет значение11

any(arow['column1'] == 'value11' for arow in table.iteritems())

Это метод формирования таблиц неправильно?

Нет, это просто очень "разоблачено", возможно, слишком много - его полезно инкапсулировать в класс, который предоставляет нужные вам методы, тогда вопрос о том, как лучше всего реализовать их, не влияет на все остальное ваше приложение. .

Есть ли лучший способ реализации такие таблицы с более легкими поисками?

После того, как вы разработали класс, интерфейс которого вы бы хотели бы использовать , вы можете поэкспериментировать с очень разными подходами к реализации и сравнить их с рабочей нагрузкой, которая представляет ваш шаблон использования Таким образом, вы можете узнать, что лучше для вас (конечно, при условии, что манипулирование таблицами и поиск являются большой частью времени выполнения вашего приложения - profile your application).

У меня были похожие, но не идентичные потребности в большом внутреннем приложении, которое я поддерживаю на работе, за исключением того, что индексы строк целочисленные (только имена столбцов являются строками), порядок столбцов важен, а рабочая нагрузка больше связана с «редактированием» «таблица (добавление, удаление, изменение порядка строк или столбцов, переименование столбцов и т. д.). Я начал с таблицы, демонстрирующей необходимые мне функциональные возможности, с самой простой и грубой внутренней реализацией (список диктов, плюс список имен столбцов для упорядочения столбцов); и к настоящему времени я развил это (независимо от фактических частей «уровня приложения», но основываясь на их профилировании и сравнительном тестировании) до совершенно разных реализаций (в настоящее время основанных на 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())

и т. Д. - напишите все методы, которые нужны вашему приложению, с полезными короткими именами, а затем, возможно, посмотрите, можете ли вы назвать некоторые из них псевдонимами как специальные методы, если они часто используются таким образом, например, возможно (предполагается, что Python 2 . * - требуется немного другой синтаксис в 3. *):

    def __setitem__(self, (row, col), val):
        self.add(row, col, val)

и так далее. Как только код заработает, , тогда наступит подходящее время для профилирования, тестирования и, возможно, внутренней оптимизации реализации.

7 голосов
/ 02 апреля 2010

Для этого я бы использовал базу данных в памяти с SQLite . Модуль sqlite даже входит в стандартную библиотеку начиная с Python 2.5, что означает, что это даже не добавляет особых требований.

0 голосов
/ 02 апреля 2010

Теперь, как мне искать, если 'column1' имеет 'значение11'

Вы спрашиваете об этом?

found= False
for r in table:
    if table[r]['column1'] == 'value11'
        found= True
        break

Это то, что вы пытаетесь сделать?

0 голосов
/ 02 апреля 2010

Вложенный список должен быть в состоянии сделать работу здесь. Я бы использовал только вложенные словари, если элементы разбросаны по сетке.

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...