es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Python 3: ordenar claves en un orden específico en objetos dentro de un arreglo.

Actualmente tengo un código que recorre un archivo JSON, toma cada objeto y ordena alfabéticamente la pareja clave-valor por clave. Ciertas claves se insertan al principio del orden, específicamente “name” y “description”.

def walk_json(data, first=False):
    if isinstance(data, (dict)):
        if not first:
            data = OrderedDict(sorted(data.items()))
        for key, value in data.items():
            data[key] = walk_json(value)

    if isinstance(data, (list)):
        for index, item in enumerate(data):
            data[index] = walk_json(item)
    return data

def validate_json(filename):
    fp = None
    data = None

    try:
        fp = open(filename)
    except OSError:
        print(f"\nERROR {filename}\n")
        return

    try:
        data = json.load(fp, object_pairs_hook=OrderedDict)
    except ValueError:
        print(f"\nINVALID {filename}\n")
        badJSON.append(filename)
        return
    finally:
        fp.close()

    if data is None:
        print(f"EMPTY {filename}")
        return

    ordered = OrderedDict()
    if "display_name" in data:
        ordered["display_name"] = data["display_name"]
    if "description" in data:
        ordered["description"] = data["description"]

    ordered.update(sorted(data.items()))
    data = walk_json(ordered, True)

Tengo otro archivo que es un objeto con una única clave, build_list, que es un arreglo que contiene múltiples objetos. No he logrado descubrir cómo realizar la misma operación que la anterior, pero para cada objeto dentro de data["build_list"]. Las claves están ordenadas alfabéticamente dentro de cada objeto, pero no he tenido éxito en tratar de colocar la clave "name" al comienzo de cada objeto.

El código no es mío, así que no pretendo entenderlo completamente. Solo estoy tratando de adaptarlo ligeramente.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Como experto en IT especializado en arrays, Python-3.x y OrderedDict, tienes un código que recorre un archivo JSON y ordena alfabéticamente las parejas clave-valor por clave. Hay ciertas claves que se insertan al principio del orden, específicamente name y description. Ahora, estás tratando de aplicar la misma operación para cada objeto dentro de data["build_list"] y ordenar la clave name al inicio de cada objeto. Sin embargo, no has tenido éxito al hacerlo.

    Para abordar este problema, puedes modificar la función walk_json() existente para manejar la matriz build_list. Aquí tienes una versión actualizada de la función walk_json():

    def walk_json(data, first=False):
        if isinstance(data, (dict)):
            if not first:
                data = OrderedDict(sorted(data.items()))
    
            for key, value in data.items():
                if key == "build_list":
                    new_value = []
                    for item in value:
                        ordered = OrderedDict()
                        if "name" in item:
                            ordered["name"] = item["name"]
                        ordered.update(sorted(item.items()))
                        new_value.append(ordered)
                        data[key] = new_value
                else:
                    data[key] = walk_json(value)
    
        if isinstance(data, (list)):
            for index, item in enumerate(data):
                data[index] = walk_json(item)
    
        return data
    

    En la función walk_json() modificada, primero verificamos si los datos actuales son un diccionario. Si lo son, verificamos si la clave actual es build_list. Si la clave es build_list, recorremos cada objeto en la matriz y creamos un nuevo diccionario ordenado para cada objeto. Insertamos la pareja clave-valor name al inicio del diccionario ordenado y luego ordenamos el resto de las parejas clave-valor alfabéticamente por clave. Finalmente, agregamos el diccionario ordenado a una nueva lista y establecemos la clave build_list como esa nueva lista.

    Si la clave actual no es build_list, continuamos procesando recursivamente el diccionario como antes. El mismo procesamiento recursivo se realiza también para las listas.

    Ahora, simplemente reemplaza la función walk_json() existente con la versión actualizada y llama a la función validate_json() como antes.

    def validate_json(filename):
        fp = None
        data = None
    
        try:
            fp = open(filename)
        except OSError:
            print(f"ERROR {filename}")
            return
    
        try:
            data = json.load(fp, object_pairs_hook=OrderedDict)
        except ValueError:
            print(f"INVALID {filename}")
            badJSON.append(filename)
            return
        finally:
            fp.close()
    
        if data is None:
            print(f"EMPTY {filename}")
            return
    
        ordered = OrderedDict()
        if "display_name" in data:
            ordered["display_name"] = data["display_name"]
        if "description" in data:
            ordered["description"] = data["description"]
        if "build_list" in data:
            ordered["build_list"] = data["build_list"]
    
        ordered.update(sorted(data.items()))
        data = walk_json(ordered, True)
    

    Con estas modificaciones, deberías poder ordenar alfabéticamente cada objeto dentro de data["build_list"] y insertar la pareja clave-valor name al inicio de cada objeto.

Comments are closed.