Структура данных для реализации словаря с несколькими индексами?

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

Пример:

x = mysticalDataStructure()
x.add(1,'karl', dog)
x.add(2,'lisa', cat)

$ x[1].age
2
$ x['karl'].age
2
$ x[1].age = 4
$ x['karl'].age
4

Есть ли что-нибудь прерванное или лучший способ опрокинуть мой собственный (мне нужен доступ через индекс (число от 0 до n с шагом 1) и через строку).

collections.ordereddict, похоже, не имеет быстрого произвольного доступа через позицию, насколько я вижу, я могу только пройти его с помощью итератора, пока не достигнет элемента i (я могу вставить его в правильном порядке).

Ответ 1

class MultiKeyDict(object):

    def __init__(self, **kwargs):
        self._keys = {}
        self._data = {}
        for k, v in kwargs.iteritems():
            self[k] = v

    def __getitem__(self, key):
        try:
            return self._data[key]
        except KeyError:
            return self._data[self._keys[key]]

    def __setitem__(self, key, val):
        try:
            self._data[self._keys[key]] = val
        except KeyError:
            if isinstance(key, tuple):
               if not key:
                  raise ValueError(u'Empty tuple cannot be used as a key')
               key, other_keys = key[0], key[1:]
            else:
               other_keys = []
            self._data[key] = val
            for k in other_keys:
                self._keys[k] = key

    def add_keys(self, to_key, new_keys):
        if to_key not in self._data:
            to_key = self._keys[to_key]
        for key in new_keys:
            self._keys[key] = to_key


    @classmethod
    def from_dict(cls, dic):
        result = cls()
        for key, val in dic.items():
            result[key] = val
        return result

Использование:

>>> d = MultiKeyDict(a=1, b=2)
>>> d['c', 'd'] = 3 # two keys for one value
>>> print d['c'], d['d']
3 3
>>> d['c'] = 4
>>> print d['d']
4
>>> d.add_keys('d', ('e',))
>>> d['e']
4
>>> d2 = MultiKeyDict.from_dict({ ('a', 'b'): 1 })
>>> d2['a'] = 2
>>> d2['b']
2

Ответ 2

Есть ли определенная причина, по которой вы не можете просто использовать словарь:

x = {}
x[1] = x['karl'] = dog
x[2] = x['lisa'] = cat

Затем вы можете получить к нему доступ.

Если вы действительно не хотите повторять свое "я", вы делаете это:

class MysticalDataStructure(dict):
    def add(self, key1, key2, value):
        return self[key1] = self[key2] = value

x = MysticalDataStructure()
x.add(1, 'karl', dog)
x.add(2, 'lisa', cat)

Ответ 3

Просто используйте три карты.

maps = [dict(), dict(), dict()]

def insert(rec):
   maps[0][rec[0]] = rec
   maps[1][rec[1]] = rec
   maps[2][rec[2]] = rec

Изменения в ключевых атрибутах объекта rec потребуют повторного ввода. Как и любая другая карта, когда вы меняете ключ объекта.

В конце концов карты только отображают ключ → объект. Они фактически не хранят копии объекта (это просто не сбор мусора). Таким образом, карта является индексом, не более того. Если вам нужны три индекса, используйте три карты. Напишите пару функций клея, чтобы управлять ими.

Как упоминалось Trevor, вы также можете использовать общий словарь:

index = dict()

def insert(rec):
    index[rec[0]] = rec
    index[rec[1]] = rec
    index[rec[2]] = rec

то вы можете получить к нему доступ.

Остерегайтесь ключевых столкновений, хотя!