¿Cuál es la diferencia entre `ordenado (lista)` y `list.sort()`?

Resuelto alvas asked hace 10 años • 7 respuestas

list.sort()ordena la lista y reemplaza la lista original, mientras que sorted(list)devuelve una copia ordenada de la lista, sin cambiar la lista original.

  • ¿Cuándo se prefiere uno sobre el otro?
  • ¿Cuál es más eficiente? ¿Por cuanto?
  • ¿Se puede revertir una lista al estado sin ordenar después de list.sort()haberla realizado?

Utilice ¿Por qué estas operaciones de lista (métodos) devuelven Ninguno, en lugar de la lista resultante? para cerrar preguntas en las que OP ha asignado inadvertidamente el resultado de .sort(), en lugar de usar sortedo una declaración separada. Una depuración adecuada revelaría que .sort()había regresado None, momento en el que "¿por qué?" es la pregunta que queda.

alvas avatar Mar 17 '14 03:03 alvas
Aceptado

sorted()devuelve una nueva lista ordenada, sin afectar la lista original. list.sort()ordena la lista in situ , muta los índices de la lista y devuelve None(como todas las operaciones in situ).

sorted()funciona en cualquier iterable, no solo en listas. Cadenas, tuplas, diccionarios (obtendrás las claves), generadores, etc., que devuelven una lista que contiene todos los elementos, ordenados.

  • Úselo list.sort()cuando desee mutar la lista, sorted()cuando desee recuperar un nuevo objeto ordenado. Úselo sorted()cuando desee ordenar algo que sea iterable, no una lista todavía .

  • Para listas, list.sort()es más rápido sorted()porque no es necesario crear una copia. Para cualquier otro iterable, no tienes otra opción.

  • No, no puedes recuperar las posiciones originales. Una vez que llamaste, list.sort()el pedido original desapareció.

Martijn Pieters avatar Mar 16 '2014 20:03 Martijn Pieters

¿Cuál es la diferencia entre sorted(list)vs list.sort()?

  • list.sortmuta la lista en el lugar y devuelveNone
  • sortedtoma cualquier iterable y devuelve una nueva lista, ordenada.

sortedes equivalente a esta implementación de Python, pero la función incorporada de CPython debería ejecutarse considerablemente más rápido tal como está escrita en C:

def sorted(iterable, key=None):
    new_list = list(iterable)    # make a new list
    new_list.sort(key=key)       # sort it
    return new_list              # return it

¿Cuándo usar cuál?

  • Úselo list.sortcuando no desee conservar el orden de clasificación original (por lo tanto, podrá reutilizar la lista in situ en la memoria) y cuando sea el único propietario de la lista (si la lista es compartida por otro código y usted mutárselo, podría introducir errores cuando se use esa lista).
  • Úselo sortedcuando desee conservar el orden de clasificación original o cuando desee crear una nueva lista que solo posea su código local.

¿Se pueden recuperar las posiciones originales de una lista después de list.sort()?

No, a menos que usted mismo haya hecho una copia, esa información se pierde porque la clasificación se realiza in situ.

"¿Y cuál es más rápido? ¿Y cuánto más rápido?"

Para ilustrar la penalidad de crear una nueva lista, use el módulo timeit, aquí está nuestra configuración:

import timeit
setup = """
import random
lists = [list(range(10000)) for _ in range(1000)]  # list of lists
for l in lists:
    random.shuffle(l) # shuffle each list
shuffled_iter = iter(lists) # wrap as iterator so next() yields one at a time
"""

Y aquí están nuestros resultados para una lista de 10000 enteros ordenados aleatoriamente. Como podemos ver aquí, hemos refutado un antiguo mito de gastos de creación de listas :

Pitón 2.7

>>> timeit.repeat("next(shuffled_iter).sort()", setup=setup, number = 1000)
[3.75168503401801, 3.7473005310166627, 3.753129180986434]
>>> timeit.repeat("sorted(next(shuffled_iter))", setup=setup, number = 1000)
[3.702025591977872, 3.709248117986135, 3.71071034099441]

Pitón 3

>>> timeit.repeat("next(shuffled_iter).sort()", setup=setup, number = 1000)
[2.797430992126465, 2.796825885772705, 2.7744789123535156]
>>> timeit.repeat("sorted(next(shuffled_iter))", setup=setup, number = 1000)
[2.675589084625244, 2.8019039630889893, 2.849375009536743]

Después de algunos comentarios, decidí que sería deseable otra prueba con características diferentes. Aquí proporciono la misma lista ordenada aleatoriamente de 100.000 de longitud para cada iteración 1.000 veces.

import timeit
setup = """
import random
random.seed(0)
lst = list(range(100000))
random.shuffle(lst)
"""

Interpreto que la diferencia de este tipo más grande proviene de la copia mencionada por Martijn, pero no domina hasta el punto indicado en la respuesta más antigua y popular aquí, aquí el aumento en el tiempo es solo de aproximadamente el 10%.

>>> timeit.repeat("lst[:].sort()", setup=setup, number = 10000)
[572.919036605, 573.1384446719999, 568.5923951]
>>> timeit.repeat("sorted(lst[:])", setup=setup, number = 10000)
[647.0584738299999, 653.4040515829997, 657.9457361929999]

También ejecuté lo anterior en un orden mucho más pequeño y vi que la nueva sortedversión de copia todavía requiere aproximadamente un 2 % más de tiempo de ejecución en un tipo de longitud de 1000.

Poke también ejecutó su propio código, aquí está el código:

setup = '''
import random
random.seed(12122353453462456)
lst = list(range({length}))
random.shuffle(lst)
lists = [lst[:] for _ in range({repeats})]
it = iter(lists)
'''
t1 = 'l = next(it); l.sort()'
t2 = 'l = next(it); sorted(l)'
length = 10 ** 7
repeats = 10 ** 2
print(length, repeats)
for t in t1, t2:
    print(t)
    print(timeit(t, setup=setup.format(length=length, repeats=repeats), number=repeats))

Encontró para una clasificación de 1000000 de longitud (ejecutó 100 veces) un resultado similar, pero solo un aumento del 5% en el tiempo, aquí está el resultado:

10000000 100
l = next(it); l.sort()
610.5015971539542
l = next(it); sorted(l)
646.7786222379655

Conclusión:

Una lista de gran tamaño que se ordena mientras sortedse realiza una copia probablemente dominará las diferencias, pero la clasificación en sí domina la operación, y organizar su código en torno a estas diferencias sería una optimización prematura. Lo usaría sortedcuando necesito una nueva lista ordenada de datos, y lo usaría list.sortcuando necesito ordenar una lista en el lugar y dejar que eso determine mi uso.

Russia Must Remove Putin avatar Mar 16 '2014 20:03 Russia Must Remove Putin

Aquí hay algunos ejemplos simples para ver la diferencia en acción:

Vea la lista de números aquí:

nums = [1, 9, -3, 4, 8, 5, 7, 14]

Al llamar sorteda esta lista, sortedse hará una copia de la misma. (Lo que significa que su lista original permanecerá sin cambios).

Vamos a ver.

sorted(nums)

devoluciones

[-3, 1, 4, 5, 7, 8, 9, 14]

mirando de numsnuevo

nums

Vemos la lista original (inalterada y NO ordenada). sortedno cambió la lista original

[1, 2, -3, 4, 8, 5, 7, 14]

Tomar la misma numslista y aplicarle la sortfunción cambiará la lista real.

Vamos a ver.

Comenzando con nuestra numslista para asegurarnos, el contenido sigue siendo el mismo.

nums

[-3, 1, 4, 5, 7, 8, 9, 14]

nums.sort()

Ahora la lista de números original ha cambiado y al mirar los números vemos que nuestra lista original ha cambiado y ahora está ordenada.

nums
[-3, 1, 2, 4, 5, 7, 8, 14]
Stryker avatar Oct 30 '2018 19:10 Stryker

Nota: La diferencia más simple entre sort() y sorted() es: sort() no devuelve ningún valor, mientras que sorted() devuelve una lista iterable.

sort() no devuelve ningún valor.

El método sort() simplemente ordena los elementos de una lista determinada en un orden específico: ascendente o descendente sin devolver ningún valor.

La sintaxis del método sort() es:

list.sort(key=..., reverse=...)

Alternativamente, también puedes usar la función incorporada de Python sorted() para el mismo propósito. función ordenada devolver lista ordenada

 list=sorted(list, key=..., reverse=...)
Projesh Bhoumik avatar Dec 06 '2018 13:12 Projesh Bhoumik