133 votes

Comment implémenter une table de hachage bidirectionnelle efficace ?

Python dict est une structure de données très utile :

d = {'a': 1, 'b': 2}

d['a'] # get 1

Parfois, vous souhaitez également indexer par valeurs.

d[1] # get 'a'

Quel est le moyen le plus efficace de mettre en œuvre cette structure de données ? Des recommandations officielles pour le faire ?

55voto

Emil Points 5513

Vous pouvez utiliser la même dictée elle-même en ajoutant clé, paire de valeur dans l'ordre inverse.

d={'a' :1,'b' :2}
revd=dict([reverse(i) for i in d.items()])
d.update(revd)

8voto

jme Points 694

L'extrait de code ci-dessous implémente une carte inversible (bijective) :

class BijectionError(Exception):
    """Must set a unique value in a BijectiveMap."""

    def __init__(self, value):
        self.value = value
        msg = 'The value "{}" is already in the mapping.'
        super().__init__(msg.format(value))


class BijectiveMap(dict):
    """Invertible map."""

    def __init__(self, inverse=None):
        if inverse is None:
            inverse = self.__class__(inverse=self)
        self.inverse = inverse

    def __setitem__(self, key, value):
        if value in self.inverse:
            raise BijectionError(value)

        self.inverse._set_item(value, key)
        self._set_item(key, value)

    def __delitem__(self, key):
        self.inverse._del_item(self[key])
        self._del_item(key)

    def _del_item(self, key):
        super().__delitem__(key)

    def _set_item(self, key, value):
        super().__setitem__(key, value)

L'avantage de cette implémentation est que l'attribut inverse d'un BijectiveMap nouveau un BijectiveMap. Par conséquent, vous pouvez faire des choses comme :

>>> foo = BijectiveMap()
>>> foo['steve'] = 42
>>> foo.inverse
{42: 'steve'}
>>> foo.inverse.inverse
{'steve': 42}
>>> foo.inverse.inverse is foo
True

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X