¿Cómo asegurar que las claves de dict de Python sean en minúsculas?

Tengo un dictado que quiero convertir en JSON usando simplejson.

¿Cómo puedo asegurarme de que todas las claves de mi dictado sean minúsculas?

{ "DISTANCE": 17.059918745802999, "name": "Foo Bar", "Restaurant": { "name": "Foo Bar", "full_address": { "country": "France", "street": "Foo Bar", "zip_code": "68190", "city": "UNGERSHEIM" }, "phone": "+33.389624300", "longitude": "7.3064454", "latitude": "47.8769091", "id": "538" }, "price": "", "composition": "", "profils": {}, "type_menu": "", "ID": "" }, 

EDIT: Gracias a todos por echar un vistazo a mi pregunta, lamento no haber explicado en detalle por qué quería esto. Fue para parchear el JSONEmitter de django-piston .

 >>> d = {"your": "DATA", "FROM": "above"} >>> dict((k.lower(), v) for k, v in d.iteritems()) {'from': 'above', 'your': 'DATA'} >>> def lower_keys(x): ... if isinstance(x, list): ... return [lower_keys(v) for v in x] ... elif isinstance(x, dict): ... return dict((k.lower(), lower_keys(v)) for k, v in x.iteritems()) ... else: ... return x ... >>> lower_keys({"NESTED": {"ANSWER": 42}}) {'nested': {'answer': 42}} 

Aquí hay una solución que prohíbe configurar una clave en minúscula:

 class LowerCaseDict(dict): def __setitem__(self, key, val): if not key.islower(): raise TypeError, "%s key must be lowercase" % key dict.__setitem__(self, key, val) ld = LowerCaseDict() ld['g']='g' 

Aquí está mi solución:

 def lower_key(in_dict): if type(in_dict) is dict: out_dict = {} for key, item in in_dict.items(): out_dict[key.lower()] = lower_key(item) return out_dict elif type(in_dict) is list: return [lower_key(obj) for obj in in_dict] else: return in_dict 

Como no has mencionado claramente lo que quieres hacer:

Convertir todas las claves a minúsculas:

 >>> y = dict((k.lower(), v) for k, v in x.iteritems()) 

Compruebe las claves:

 >>> for k in x.iterkeys(): if k.islower(): print k, 'True' else: print k, 'False' 

Si solo quiere comprobar si están en minúsculas (su redacción, usando “asegurar”, no está claro, pero sospecho que no es lo que quiere), puede hacerlo de forma compacta en una línea:

 all(k.islower() for k in x.iterkeys()) 

Aquí hay una solución completa.

 from requests import CaseInsensitiveDict 

O si quieres ver el código:

 class CaseInsensitiveDict(dict): """Basic case insensitive dict with strings only keys.""" proxy = {} def __init__(self, data): self.proxy = dict((k.lower(), k) for k in data) for k in data: self[k] = data[k] def __contains__(self, k): return k.lower() in self.proxy def __delitem__(self, k): key = self.proxy[k.lower()] super(CaseInsensitiveDict, self).__delitem__(key) del self.proxy[k.lower()] def __getitem__(self, k): key = self.proxy[k.lower()] return super(CaseInsensitiveDict, self).__getitem__(key) def get(self, k, default=None): return self[k] if k in self else default def __setitem__(self, k, v): super(CaseInsensitiveDict, self).__setitem__(k, v) self.proxy[k.lower()] = k