4

dict現在、組み込み型と同様の機能を持つ Python コンテナー クラスが必要です。基本的に、私が必要としているのは、主キーの横に任意の数のキーがあり、まったく同じ値にマップされる辞書です。ただし、それを反復するときは(primary_key, value)、キーのリストが要求された場合はペアと主キーのみを反復する必要があります。

これがすでに実装されている場合は、車輪の再発明はしたくありません。そのようなコンテナを提供するモジュールはすでにありますか? そうでない場合は、自分で実装します。

4

3 に答える 3

2

Here is a quick implementation:

class MultipleKeyDict(dict):
    __slots__ = ["_primary_keys"]
    def __init__(self, arg=None, **kwargs):
        self._primary_keys = {}
        self.update(arg, **kwargs)
    def __setitem__(self, key, value):
        super(MultipleKeyDict, self).__setitem__(key, value)
        self._primary_keys.setdefault(value, key)
    def __delitem__(self, key):
        value = self[key]
        super(MultipleKeyDict, self).__delitem__(key)
        if self._primary_keys[value] == key:
            del self._primary_keys[value]
            for k, v in super(MultipleKeyDict, self).iteritems():
                if v == value:
                    self._primary_keys[value] = k
                    break
    def __iter__(self):
        return self.iterkeys()
    def update(self, arg=None, **kwargs):
        if arg is not None:
            if isinstance(arg, collections.Mapping):
                for k in arg:
                    self[k] = arg[k]
            else:
                for k, v in arg:
                    self[k] = v
        for k in kwargs:
            self[k] = kwargs[k]
    def clear(self):
        super(MultipleKeyDict, self).clear()
        self._primary_keys.clear()
    def iteritems(self):
        for v, k in self._primary_keys.iteritems():
            yield k, v
    def items(self):
        return list(self.iteritems())
    def itervalues(self):
        return self._primary_keys.iterkeys()
    def values(self):
        return self._primary_keys.keys()
    def iterkeys(self):
        return self._primary_keys.itervalues()
    def keys(self):
        return self._primary_keys.values()

The only messy bit is that it has to search the whole dict in case a primary key gets deleted.

I omitted copy(), pop(), popitem() and setdefault(). If you need them, you'll have to implement them yourself.

于 2011-11-28T18:52:42.217 に答える
1

最も単純で簡単な解決策は、2 つのディクショナリを使用することです。そのうちの 1 つは、セカンダリ キーをプライマリ キーにマップします。何らかの理由で逆マッピングが必要な場合は、それをプライマリ ディクショナリに含めることができます。

sec = {'one': 'blue', 'two': 'red', 'three': 'blue',   # seconary keys
       'blue': 'blue', 'red': 'red'}                   # include identity mapping for primaries
dict = {'blue': ('doll', '$9.43', ('one', 'three')),
        'red':  ('truck', '$14.99', ('two',)) }

record = dict[sec['two']]
print('Toy=', record[0], 'Price=', record[1])
于 2011-11-28T18:39:55.213 に答える
0

複数のキー辞書の python パッケージが追加されました。
https://pypi.python.org/pypi/multi_key_dict/1.0.2

リンクから:

from multi_key_dict import multi_key_dict

k = multi_key_dict()
k[1000, 'キロ', 'k'] = 'キロ (x1000)'

print k[1000] # 'キロ (x1000)' を出力します
print k['k'] # 'kilo (x1000)' も出力します

# オブジェクトを更新、削除するのと同じ方法:
# オブジェクトが 1 つのキーを使用して更新された場合、新しい値は
# 上記の例のように、他のキーを使用してアクセスできるようにします。
k['キロ'] = 'キロ'
print k[1000] # 値が更新されたため、「キロ」が出力されます
于 2013-09-12T00:57:31.320 に答える