Was ist der Unterschied zwischen `sorted (list)` vs `list.sort ()`?

list.sort() sortiert die Liste und speichert die sortierte Liste, während sorted(list) eine sortierte Kopie der Liste zurückgibt, ohne die ursprüngliche Liste zu ändern.

  • Aber wann soll was benutzt werden?
  • Und was ist schneller? Und wie viel schneller?
  • Können die ursprünglichen Positionen einer Liste nach list.sort() abgerufen werden?

sorted() gibt eine neue sortierte Liste zurück und lässt die ursprüngliche Liste unberührt. list.sort() sortiert die Liste an Ort und Stelle , mutiert die list.sort() und gibt None (wie alle In-Place-Operationen) zurück.

sorted() funktioniert auf allen iterierbaren Listen, nicht nur auf Listen. Strings, Tupel, Wörterbücher (Sie erhalten die Schlüssel), Generatoren usw., die eine Liste mit allen Elementen zurückgeben, sortiert.

  • Verwenden Sie list.sort() wenn Sie die Liste mutieren möchten, sorted() wenn Sie ein neues sortiertes Objekt zurück haben möchten. Verwenden Sie sorted() wenn Sie etwas sortieren möchten, das iterierbar ist, noch keine Liste.

  • Bei Listen ist list.sort() schneller als sorted() da keine Kopie erstellt werden muss. Für jedes andere iterable haben Sie keine Wahl.

  • Nein, Sie können die ursprünglichen Positionen nicht abrufen. Sobald Sie list.sort() aufgerufen list.sort() , ist die ursprüngliche Reihenfolge verschwunden.

Was ist der Unterschied zwischen sorted(list) vs list.sort() ?

  • list.sort mutiert die Liste list.sort und gibt None
  • sorted nimmt alle iterable und gibt eine neue Liste sortiert zurück.

sorted ist äquivalent zu dieser Python-Implementierung, aber die eingebaute CPython-function sollte messbar schneller laufen, da sie in C geschrieben ist:

 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 

Wann benutzt man was?

  • Verwenden Sie list.sort wenn Sie die ursprüngliche Sortierreihenfolge nicht beibehalten möchten (Sie können die Liste dann im Speicher wiederverwenden.) Und wenn Sie der alleinige Eigentümer der Liste sind (wenn die Liste von anderen geteilt wird) Code und du mutierst es mutieren, könntest du Bugs einführen wo diese Liste benutzt wird.)
  • Verwenden Sie sorted wenn Sie die ursprüngliche Sortierreihenfolge beibehalten möchten oder wenn Sie eine neue Liste erstellen möchten, die nur Ihr lokaler Code besitzt.

Können die ursprünglichen Positionen einer Liste nach list.sort () abgerufen werden?

Nein – es sei denn, Sie haben selbst eine Kopie erstellt, diese Informationen gehen verloren, da die Sortierung direkt erfolgt.

“Und was ist schneller? Und wie viel schneller?”

Um den Nachteil der Erstellung einer neuen Liste zu verdeutlichen, verwenden Sie das Modul “timeit”, hier ist unser Setup:

 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 """ 

Und hier sind unsere Ergebnisse für eine Liste von zufällig angeordneten 10000 Ganzzahlen. Wie wir hier sehen können, haben wir einen älteren Mythos der Listenerstellungskosten widerlegt:

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] 

Nach einigen Rückmeldungen entschied ich, dass ein anderer Test mit anderen Eigenschaften wünschenswert wäre. Hier stelle ich die gleiche zufällig geordnete Liste von 100.000 in der Länge für jede Iteration 1.000mal zur Verfügung.

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

Ich interpretiere den Unterschied dieser größeren Sorte aus dem von Martijn erwähnten Kopieren, aber er dominiert nicht den Punkt, der in der älteren, populäreren Antwort hier angegeben ist, hier beträgt die Zunahme der Zeit nur etwa 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] 

Ich führte das oben genannte auch auf eine viel kleinere Art und sah, dass die neue sorted Kopie Version immer noch etwa 2% längere Laufzeit auf einer Art von 1000 Länge dauert.

Poke hat auch seinen eigenen Code, hier ist der Code:

 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)) 

Er fand für 1000000 Länge sort, (lief 100 mal) ein ähnliches Ergebnis, aber nur etwa 5% mehr Zeit, hier ist die Ausgabe:

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

Fazit:

Eine große sortierte Liste, die sorted und eine Kopie erstellt, wird wahrscheinlich die Unterschiede dominieren, aber die Sortierung selbst dominiert die Operation, und die Organisation Ihres Codes um diese Unterschiede wäre eine vorzeitige Optimierung. Ich würde sorted wenn ich eine neue sortierte Liste der Daten brauche, und ich würde list.sort wenn ich eine Liste an Ort und Stelle sortieren muss, und diese meine Verwendung bestimmen lassen.

Der Hauptunterschied besteht darin, dass sorted(some_list) eine neue list zurückgibt:

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

und some_list.sort() , sortiert die Liste an Ort und Stelle :

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

Beachten Sie, dass a.sort() keine a.sort() , da a.sort() nichts print a.sort() .


Kann eine Liste der ursprünglichen Positionen nach list.sort () abgerufen werden?

Nein, weil es die ursprüngliche Liste ändert.

Die function .sort () speichert den Wert einer neuen Liste direkt in der Listenvariablen. also antworte auf deine dritte Frage wäre NEIN. Auch wenn Sie dies mit sortierten (Liste) tun, können Sie es verwenden, weil es nicht in der Listenvariablen gespeichert ist. Auch manchmal .sort () -Methode fungiert als function oder sagen, dass es Argumente in sich trägt.

Sie müssen den Wert von sorted (list) explizit in einer Variablen speichern.

Auch für kurze Datenverarbeitung wird die Geschwindigkeit keinen Unterschied machen; aber für lange Listen; Sie sollten direkt .sort () -Methode für schnelle Arbeit verwenden; aber wieder werden Sie irreversiblen Handlungen gegenüberstehen.