python json duplicates key

El analizador Python json permite claves duplicadas



duplicates key (2)

Muchas gracias @Lukas Graf, también lo hice funcionar implementando mi propia versión de la función de enlace

def dict_raise_on_duplicates(ordered_pairs): count=0 d=collections.OrderedDict() for k,v in ordered_pairs: if k in d: d[k+''_dupl_''+str(count)]=v count+=1 else: d[k]=v return d

Lo único que queda es deshacerse automáticamente de los corchetes dobles y he terminado: D Gracias de nuevo

Necesito analizar un archivo json que desafortunadamente para mí no sigue el prototipo. Tengo dos problemas con los datos, pero ya he encontrado una solución para ellos, así que solo los mencionaré al final, tal vez alguien pueda ayudarme allí también.

Entonces necesito analizar entradas como esta:

"Test":{ "entry":{ "Type":"Something" }, "entry":{ "Type":"Something_Else" } }, ...

El analizador predeterminado json actualiza el diccionario y, por lo tanto, usa solo la última entrada. Tengo que almacenar de alguna manera el otro también, y no tengo idea de cómo hacerlo. También TENGO que almacenar las claves en varios diccionarios en el mismo orden en que aparecen en el archivo, por eso estoy usando un OrderedDict para hacerlo. funciona bien, así que si hay alguna forma de expandir esto con las entradas duplicadas, estaría agradecido.

Mi segundo problema es que este mismo archivo json contiene entradas como esa:

"Test":{ { "Type":"Something" } }

La función Json.load () genera una excepción cuando llega a esa línea en el archivo json. La única forma en que pude solucionar esto fue eliminar manualmente los soportes internos.

Gracias por adelantado


Puede usar JSONDecoder.object_pairs_hook para personalizar cómo JSONDecoder decodifica objetos. A esta función de enlace se le pasará una lista de pares (key, value) que generalmente realiza algún procesamiento y luego se convertirá en una dict .

Sin embargo, dado que los diccionarios Python no permiten claves duplicadas (y simplemente no puede cambiar eso), puede devolver los pares sin cambios en el gancho y obtener una lista anidada de pares (key, value) cuando decodifica su JSON:

from json import JSONDecoder def parse_object_pairs(pairs): return pairs data = """ {"foo": {"baz": 42}, "foo": 7} """ decoder = JSONDecoder(object_pairs_hook=parse_object_pairs) obj = decoder.decode(data) print obj

Salida:

[(u''foo'', [(u''baz'', 42)]), (u''foo'', 7)]

La forma en que use esta estructura de datos depende de usted. Como se indicó anteriormente, los diccionarios de Python no permitirán claves duplicadas, y no hay forma de evitarlo. ¿Cómo harías una búsqueda basada en una clave? dct[key] sería ambiguo.

Por lo tanto, puede implementar su propia lógica para manejar una búsqueda de la manera en que espera que funcione, o implementar algún tipo de evitación de colisión para hacer que las claves sean únicas si no lo son, y luego crear un diccionario a partir de su lista anidada.

Editar : como dijo que le gustaría modificar la clave duplicada para que sea única, así es como lo haría:

from collections import OrderedDict from json import JSONDecoder def make_unique(key, dct): counter = 0 unique_key = key while unique_key in dct: counter += 1 unique_key = ''{}_{}''.format(key, counter) return unique_key def parse_object_pairs(pairs): dct = OrderedDict() for key, value in pairs: if key in dct: key = make_unique(key, dct) dct[key] = value return dct data = """ {"foo": {"baz": 42, "baz": 77}, "foo": 7, "foo": 23} """ decoder = JSONDecoder(object_pairs_hook=parse_object_pairs) obj = decoder.decode(data) print obj

Salida:

OrderedDict([(u''foo'', OrderedDict([(u''baz'', 42), (''baz_1'', 77)])), (''foo_1'', 7), (''foo_2'', 23)])

La función make_unique es responsable de devolver una clave libre de colisión. En este ejemplo, solo sufija la clave con _n donde n es un contador incremental, solo adáptelo a sus necesidades.

Debido a que object_pairs_hook recibe los pares exactamente en el orden en que aparecen en el documento JSON, también es posible preservar ese orden utilizando un OrderedDict , también lo OrderedDict .