sort lists lista python list sorting copy in-place

lists - sort() python



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

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

  • list.sort muta la lista in situ y devuelve None
  • sorted toma cualquier iterable y devuelve una nueva lista, ordenada.

sorted es equivalente a esta implementación de Python, pero la función incorporada CPython debe ejecutarse mensurablemente más rápido, ya que está escrito en C:

def sorted(original_list): list_copy = list(original_list) # make a copy list_copy.sort() # sort it return list_copy # return the copied and sorted list

(Para copiar, podríamos haber usado un segmento o en Python 3, list.copy, pero la list es lo suficientemente clara para nuestros propósitos).

cuándo usar cual?

  • Use list.sort cuando no desee conservar el orden de clasificación original (por lo tanto, podrá reutilizar la lista en su lugar en la memoria) y cuando sea el único propietario de la lista (si la lista es compartida por otra persona). código y lo muta, podría introducir errores donde se usa esa lista).
  • Utilícelo sorted cuando desee conservar el orden de clasificación original o cuando desee crear una lista nueva 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 haya hecho una copia usted mismo, esa información se pierde porque el ordenamiento se realiza en el lugar.

"¿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 de tiempo, 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 viejo mito de gastos de creación de listas :

Python 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]

Python 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 diferentes características. 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 la diferencia de este tipo más grande proveniente de la copia mencionada por Martijn, pero no domina al punto establecido en la respuesta más antigua más popular aquí, aquí el aumento en el tiempo es solo de aproximadamente 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é el anterior en un tipo mucho más pequeño, y vi que la nueva versión de copia sorted aún tarda aproximadamente un 2% más de tiempo de ejecución en una especie de 1000 de longitud.

Poke ejecutó su propio código también, 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ó una clasificación de 1000000 de longitud, (ejecutó 100 veces) un resultado similar, pero solo un aumento de 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 ordene con una copia sorted probablemente dominará las diferencias, pero la clasificación en sí misma domina la operación, y organizar su código alrededor de estas diferencias sería una optimización prematura. list.sort sorted cuando necesite una nueva lista ordenada de los datos, y usaría list.sort cuando necesite ordenar una lista en el lugar, y dejar que eso determine mi uso.

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

  • Pero cuando usar cual?
  • ¿Y cuál es más rápido? ¿Y cuánto más rápido?
  • ¿Se pueden recuperar las posiciones originales de una lista después de list.sort() ?

La función .sort () almacena el valor de la nueva lista directamente en la variable de la lista; entonces la respuesta para su tercera pregunta sería NO. Además, si hace esto utilizando ordenado (lista), puede obtenerlo porque no está almacenado en la variable de la lista. También a veces el método .sort () actúa como función, o dice que contiene argumentos.

Debe almacenar el valor de sorted (list) en una variable explícitamente.

También para el procesamiento de datos cortos, la velocidad no tendrá diferencias; pero para largas listas; deberías usar directamente el método .sort () para un trabajo rápido; pero de nuevo enfrentarás acciones irreversibles.


La principal diferencia es que sorted(some_list) devuelve una nueva list :

a = [3, 2, 1] print sorted(a) # new list print a # is not modified

y some_list.sort() , ordena la lista en su lugar :

a = [3, 2, 1] print a.sort() # in place print a # it''s modified

Tenga en cuenta que dado que a.sort() no devuelve nada, print a.sort() imprimirá None .

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

No, porque modifica la lista original.


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

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

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

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

  • No, no puedes recuperar las posiciones originales. Una vez que haya llamado a list.sort() el orden original se list.sort() ido.