Словари с более чем одним ключом на значение в Python - PullRequest
1 голос
/ 15 января 2011

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

Я рассмотрел несколько возможных реализаций:

  1. Использование двух отдельных словарей, один длязначения данных, упорядоченные по номеру, и одно для значений данных, упорядоченных по имени.

  2. Простое назначение двух ключей одному значению в словаре.

  3. Создание словарей, сопоставляющих каждое имя с соответствующим номером, и наоборот

  4. Попытка создать хеш-функцию, которая сопоставляет каждое имя с номером и т. Д. (Относится к вышеупомянутому)

  5. Создание объекта для инкапсуляции всех трех частей данных, затем использование одного ключа для сопоставления ключей словаря с объектами и простой поиск в словаре для сопоставления другого ключа с объектом.

Ничто из этого не кажется идеальным.Первое кажется уродливым и несостоятельным.Второе тоже кажется хрупким.Третий / четвертый кажется правдоподобным, но, похоже, требует либо много ручной спецификации, либо слишком сложной реализации.Наконец, пятый теряет производительность в постоянном времени для одного из поисков.

В C / C ++ я считаю, что я использовал бы указатели для ссылки на один и тот же фрагмент данных из разных ключей.

Я знаю, что эта проблема довольно похожа на проблему поиска в базе данных по неключевому столбцу, однако я хотел бы (если это возможно) поддерживать приблизительную производительность O (1) словарей Python.

Чтосамый питонский способ достижения этой структуры данных?

Ответы [ 4 ]

5 голосов
/ 15 января 2011
In C/C++, I believe that I would use pointers to reference the same piece of 
data from different keys.

Это соответствует варианту № 2. В Python словари действительно хранят указатели на объекты. Это означает, что наличие двух ключей, указывающих на один и тот же объект, не создаст объект дважды.

1 голос
/ 15 января 2011

В C / C ++ я считаю, что я использовал бы указатели для ссылки на один и тот же фрагмент данных из разных ключей.

Почти все в Python квалифицируется как "указатель C / C ++".

Используйте ваш вариант # 1, два словаря и проверьте его на производительность. Если вы определяете класс для контента, то конструкторы и деструкторы могут управлять словарями, а класс может определять функции для поиска.

1 голос
/ 15 января 2011

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

Вариант 5 на практике пытается создать такую ​​упрощенную базу данных.И в результате, когда вы создаете такую ​​базу данных в памяти, вы получаете сопоставление UID со значениями, которые у вас есть (в данном случае только один, поскольку у вас есть только одно значение «столбец»), а индексы сопоставляются из значений в UID..

В вашем случае у вас уже есть номер, который вы можете использовать в качестве UID, поэтому вам не нужен «столбец» для этого.

Это означает, что вы в конечном итогедва словаря: одно сопоставление числа со значением и одно сопоставление имени с числом.

Так вот, что вы должны сделать, ИМО.

1 голос
/ 15 января 2011

Имена, и номера уникальны? Использование одного для поиска другого, во-первых, не так уж и плохо.

И два словаря, указывающие на одни и те же данные, как в C, не будут дублировать данные, и это тоже хорошо.

Инкапсуляция двух диктонаров в отдельный объект с add(name,number,value) и findByName(name), findByNumber(number), позволит вам централизовать обслуживание, быть тестируемым и т.

(простите за верблюда):

...