2010-11-23 14 views
8

Estoy serializando varios diccionarios anidados en JSON usando Python con simplejson.Excluir valores vacíos/nulos de la serialización JSON

¿Hay alguna manera de excluir automáticamente valores vacíos/nulos?

Por ejemplo, serializar esto:

{ 
    "dict1" : { 
    "key1" : "value1", 
    "key2" : None 
    } 
} 

a

{ 
    "dict1" : { 
    "key1" : "value1" 
    } 
} 

Al usar Jackson con Java puede utilizar Inclusion.NON_NULL para hacer esto. ¿Hay un simple equivalente de Json?

Respuesta

11
def del_none(d): 
    """ 
    Delete keys with the value ``None`` in a dictionary, recursively. 

    This alters the input so you may wish to ``copy`` the dict first. 
    """ 
    # For Python 3, write `list(d.items())`; `d.items()` won’t work 
    # For Python 2, write `d.items()`; `d.iteritems()` won’t work 
    for key, value in list(d.items()): 
     if value is None: 
      del d[key] 
     elif isinstance(value, dict): 
      del_none(value) 
    return d # For convenience 

Ejemplo de uso:

>>> mydict = {'dict1': {'key1': 'value1', 'key2': None}} 
>>> print(del_none(mydict.copy())) 
{'dict1': {'key1': 'value1'}} 

A continuación, se puede alimentar a que json.

+0

Em .... Eso produce 'RuntimeError: tamaño de diccionario cambiado durante la iteración' con Python 3.5 –

+0

' '' def del_none (d): "" " Eliminar claves con el valor' 'None'' y cadena vacía en un diccionario, de forma recursiva. Esto no altera de entrada, pero los ejemplares diccionario. diccionarios niño también se copian. no hay otros objetos se copian. """ rez = d.copy() para la clave, el valor de d .items(): si el valor es None o value == '': del rez [key] elif isinstance (value, dict): rez [key] = del_none (valor) return re z''' –

+1

@AleksandrPanzin: He actualizado el código para apuntar a Python 3 con notas para Python 2. ¡Este * fue * escrito hace siete años! Sin embargo, lo dejé como una modificación en el lugar. –

0
def excludeNone(d): 
    for k in list(d): 
     if k in d: 
      if type(d[k]) == dict: 
       excludeNone(d[k]) 
      if not d[k]: 
       del d[k] 
+4

Sería más seguro utilizar 'si d [k] no es None' en lugar de' if not d [k] '; de lo contrario, las cadenas vacías y los valores 0 también se excluirán de la salida. –

6
>>> def cleandict(d): 
...  if not isinstance(d, dict): 
...   return d 
...  return dict((k,cleandict(v)) for k,v in d.iteritems() if v is not None) 
... 
>>> mydict = dict(dict1=dict(key1='value1', key2=None)) 
>>> print cleandict(mydict) 
{'dict1': {'key1': 'value1'}} 
>>> 

no me gusta usar del en general, cambiar el diccionario existente puede tener efectos sutiles en función de cómo se crean. La creación de nuevos diccionarios con None eliminado previene todos los efectos secundarios.

Cuestiones relacionadas