12

我正在寻找一种数据结构,它在两个不同的索引下保存相同的值,我可以通过其中一个来访问数据。

例子:

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

是否有任何预先滚动的内容,或者我自己滚动的最佳方法是什么(我需要通过索引(以 1 为增量从 0 到 n 的数字)和通过字符串访问)。

collections.ordereddict似乎无法通过该位置进行快速随机访问,据我所知,我只能使用迭代器遍历它,直到到达元素i(我可以按正确的顺序插入)。

4

3 回答 3

12

您不能只使用字典是否有特殊原因:

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)
于 2012-06-19T16:22:24.603 回答
10
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
于 2012-06-19T17:12:12.767 回答
1

只需使用三张地图。

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

那么您可以通过其中任何一个访问它。

不过要小心键冲突!

于 2012-06-19T16:20:29.133 回答