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.

Ordenar por un elemento en una lista de listas de tamaño fijo y eliminar duplicados.

Me gustaría encontrar la mejor manera de lograr esto. (Ya puedo hacerlo manualmente, pero estoy buscando una biblioteca que lo haga directamente).

Quiero ordenar una lista de listas basándome en el primer índice y eliminar los duplicados del primer índice.

Las secciones son:

sections = [
    [1, 4, 1],
    [5, 3, 2],  # Ordenar por el primer elemento de sublistas
    [2, 2, 3],
    [2, 1, 4],  # Duplicado a eliminar
]

La afirmación es:

assertion = [
    [1, 4, 1],
    [2, 2, 3],
    [5, 3, 2],
]

La función debe de cumplir con lo siguiente:

def sort_first_and_remove_double(sections):

    return result

No quiero usar ningún bucle directamente, pero hacerlo en una o dos líneas utilizando bibliotecas, por razones de optimización, mis datos son enormes.

Mi código de intento está aquí:

def sort_first_and_remove_double(sections):
    sections = remove_double(sections)
    sections = sort_sections(sections)
    return sections


def sort_sections(sections):
    ids = get_ids(sections)
    return [x for _, x in sorted(zip(ids, sections))]


def remove_double(sections):
    ids = get_ids(sections)
    keeped_sections = []
    for i, id_check in enumerate(ids):
        ids_keeped = get_ids(keeped_sections)
        if id_check not in ids_keeped:
            keeped_sections.append(sections[i])
    return keeped_sections


def get_ids(sections):
    return [section[0] for section in sections]

¡Pero es muy lento!

Edición: Aquí hay una actualización de los tiempos:

t0 = time.perf_counter()
sort_first_and_remove_double(lst)
print(time.perf_counter() - t0)  # 7.719699351582676e-05 s
t0 = time.perf_counter()
list(dict(map(lambda x: [x[1][0], x[1]], sorted(enumerate(lst), key=lambda pair: (pair[1][0], -pair[0])))).values())
print(time.perf_counter() - t0)  # 7.587004802189767e-06 s
t0 = time.perf_counter()
sorted(dict(map(lambda x: (x[0], x), lst[::-1])).values())
print(time.perf_counter() - t0)  # 3.0700030038133264e-06 s
Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para ordenar una lista de listas basada en el primer índice y eliminar duplicados del primer índice de una manera más eficiente sin utilizar bucles y aprovechando las bibliotecas incorporadas, un enfoque posible es:

    import itertools
    
    def sort_first_and_remove_double(sections):
        # Ordenar la lista de listas basada en el primer índice
        sections.sort(key=lambda x: x[0])
        # Eliminar duplicados del primer índice
        sections = [list(v) for k, v in itertools.groupby(sections, key=lambda x: x[0])]
        return sections
    

    Aquí, se utiliza la función sort() para ordenar la lista de listas basada en el primer índice. Luego, se utiliza la función groupby() del módulo itertools para agrupar los elementos con el mismo primer índice y solo se conserva la primera aparición de cada grupo. Finalmente, el resultado se reconvierte en una lista de listas.

    Con esta implementación, la función se puede llamar de la siguiente manera:

    sections = [
        [1, 4, 1],
        [5, 3, 2],
        [2, 2, 3],
        [2, 1, 4],
    ]
    
    assertion = [
        [1, 4, 1],
        [2, 2, 3],
        [5, 3, 2],
    ]
    
    assert sort_first_and_remove_double(sections) == assertion
    

    Esta solución es más eficiente que las funciones proporcionadas remove_double(), get_ids(), y sort_sections(), ya que solo requiere dos líneas de código y aprovecha las bibliotecas incorporadas. Para conjuntos de datos muy grandes, esto debería proporcionar una mejora significativa en el rendimiento.

Comments are closed.