2012-05-09 17 views
5

Busco una manera fácil de ser capaz de obtener un valor de un diccionario, y si no está allí, devolver la llave que el usuario se ha pasado.diccionario Python retorno pidió clave si el valor no existe

por ejemplo:

>>> lookup = defaultdict(magic) 
>>> print lookup['DNE'] 
'DNE' 
>>> print lookup.get('DNE') 
'DNE' 
>>> print lookup['exists'] 
'some other value' 
>>> print lookup.get('exists') 
'some other value' 

Estos siempre será cuerdas, pero básicamente estoy creando un mapa idioma y necesitan una manera fácil de obtener un valor, si es que existe regresar en otro devolver la llave.

¿Hay alguna manera fácil de hacerlo? ¿O debería extender el dict y hacerlo manualmente?

+3

Iba a sugerir extender dict. Ese es el enfoque correcto de la OMI. – 10flow

Respuesta

2

debería ser posible con una función lambda

from collections import defaultdict 
a = defaultdict((lambda : 'DNE')) 

Edit: Lo siento leí mal la pregunta. Como el comentario anterior ya dijo. El camino a seguir es extender la clase dict.

>>> class mydict(dict): 
...  def __missing__(self,key): 
...   return key 
... 
>>> a = mydict() 
>>> a['asd'] 
'asd' 
+0

Nunca supe que faltaba ... esto no funciona con a.get ('asd') – Nix

14

No creo que defaultdict lo ayude aquí porque la función que genera el valor predeterminado no tiene acceso a la clave solicitada.

Sin embargo utiliza un diccionario ordinario y utiliza get con un valor por defecto:

>>> lookup = {} 
>>> key = 'DNE' 
>>> lookup.get(key, key) 
'DNE' 
+0

Así que, en resumen, ¿debería extender dict y anular get y __item__? – Nix

+0

@Nix: si quiere extender el dict entonces creo que podría usar la solución publicada por Moe. Mi respuesta muestra cómo puedes hacerlo sin extender el dict. –

+0

Su solución no me ayuda, estoy tratando de evitar tener que usar get por defecto. – Nix

2

Esto funciona bajo Python 2.7 como mínimo:

from collections import defaultdict 

class KeyAwareDefaultDict(defaultdict): 
    def __missing__(self, key): 
     if self.default_factory is None: 
      raise KeyError(key) 
     self[key] = value = self.default_factory(key) 
     return value 

lookup = KeyAwareDefaultDict((lambda key: key)) 

A diferencia de la norma dict, defaultdict.get() parece llamar __missing__ también, así que tiene una mejor base para la extensión.

Cuestiones relacionadas