Aquí es una clase para un bidireccional dict
, inspirado por Finding key from value in Python dictionary y modificado para permitir la siguiente 2) y 3).
Tenga en cuenta que:
- 1) El directorio inversa
bd.inverse
actualizaciones automáticas a sí mismo cuando el dict estándar bd
se modifica
- 2) El directorio inversa
bd.inverse[value]
es siempre una lista de key
tal que bd[key] == value
- 3) A diferencia del módulo
bidict
desde https://pypi.python.org/pypi/bidict, aquí podemos tener 2 claves con el mismo valor, esto es muy importante.
Código:
class bidict(dict):
def __init__(self, *args, **kwargs):
super(bidict, self).__init__(*args, **kwargs)
self.inverse = {}
for key, value in self.iteritems():
self.inverse.setdefault(value,[]).append(key)
def __setitem__(self, key, value):
if key in self:
self.inverse[self[key]].remove(key)
super(bidict, self).__setitem__(key, value)
self.inverse.setdefault(value,[]).append(key)
def __delitem__(self, key):
self.inverse.setdefault(self[key],[]).remove(key)
if self[key] in self.inverse and not self.inverse[self[key]]:
del self.inverse[self[key]]
super(bidict, self).__delitem__(key)
Ejemplo de uso:
bd = bidict({'a': 1, 'b': 2})
print bd # {'a': 1, 'b': 2}
print bd.inverse # {1: ['a'], 2: ['b']}
bd['c'] = 1 # Now two keys have the same value (= 1)
print bd # {'a': 1, 'c': 1, 'b': 2}
print bd.inverse # {1: ['a', 'c'], 2: ['b']}
del bd['c']
print bd # {'a': 1, 'b': 2}
print bd.inverse # {1: ['a'], 2: ['b']}
del bd['a']
print bd # {'b': 2}
print bd.inverse # {2: ['b']}
bd['b'] = 3
print bd # {'b': 3}
print bd.inverse # {2: [], 3: ['b']}
Si se prefiere, se puede suponer que los valores son inmutables, así como teclas son. –
¿Qué devolverías por este dict: {'a': 1, 'b': 2, 'A': 1} – PaulMcG
@PaulMcGuire: Yo devolvería '{1: ['a', 'A'], 2 : 'b'} '. Vea mi respuesta para tal manera de hacerlo. – Basj