web-dev-qa-db-de.com

Was ist der Unterschied zwischen `sortiert (Liste)` 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 was verwenden? 
  • Und was ist schneller? Und wie viel schneller?
  • Können die ursprünglichen Positionen einer Liste nach list.sort() abgerufen werden?
126
alvas

sorted() gibt eine sortierte Liste nach new zurück, wobei die ursprüngliche Liste nicht betroffen ist. list.sort() sortiert die Liste in-place , ändert die Listenindizes und gibt None zurück (wie alle In-Place-Vorgänge).

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

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

  • 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() angerufen haben, ist die ursprüngliche Bestellung weg.

220
Martijn Pieters

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

  • list.sort ändert die Liste an Ort und Stelle und gibt None zurück
  • sorted nimmt alle Iterationen und gibt eine neue Liste zurück, sortiert.

sorted entspricht dieser Python-Implementierung, aber die eingebaute CPython-Funktion sollte messbar schneller ausgeführt werden, 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 welche benutzen?

  • Verwenden Sie list.sort, wenn Sie die ursprüngliche Sortierreihenfolge nicht beibehalten möchten (So können Sie die Liste an Ort und Stelle im Speicher wiederverwenden.) Und wenn Sie der alleinige Eigentümer der Liste sind (falls die Liste wird von anderem Code geteilt, und Sie mutieren es, Sie könnten Fehler einführen, wenn diese Liste verwendet wird.)
  • Verwenden Sie sorted, wenn Sie die ursprüngliche Sortierreihenfolge beibehalten oder 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. Wenn Sie nicht selbst eine Kopie angefertigt haben, gehen diese Informationen verloren, da die Sortierung direkt erfolgt.

"Und was ist schneller? Und wie viel schneller?"

Um die Strafe beim Erstellen einer neuen Liste zu veranschaulichen, verwenden Sie das Zeitmodul. 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 Mythos zur Erstellung älterer Listen 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 einiger Rückmeldung entschied ich, dass ein anderer Test mit anderen Eigenschaften wünschenswert wäre. Hier stelle ich für jede Iteration 1.000 Mal dieselbe zufällig geordnete Liste mit einer Länge von 100.000 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 der von Martijn erwähnten Kopie, aber sie dominiert nicht bis zu dem Punkt, der in der älteren, populäreren Antwort hier angegeben wurde. Hier beträgt die Zeitvergrößerung 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 habe das obige auch mit einer viel kleineren Sortierung ausgeführt und habe festgestellt, dass die neue Version der sorted-Version noch etwa 2% längere Laufzeit auf einer Sorte von 1000 Länge benötigt.

Poke lief 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 Sortierung (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 Liste, die mit sorted beim Erstellen einer Kopie sortiert wird, wird wahrscheinlich die Unterschiede dominieren, aber die Sortierung selbst dominiert die Operation, und wenn Sie Ihren Code um diese Unterschiede herum organisieren, wäre dies eine vorzeitige Optimierung. Ich würde sorted verwenden, wenn ich eine neue sortierte Liste der Daten brauche, und ich würde list.sort verwenden, wenn ich eine Liste an Ort und Stelle sortieren muss und dies meine Verwendung bestimmen lässt.

28
Aaron Hall

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

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

und some_list.sort(), sortiert die Liste in place:

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

Hinweis Da a.sort() nichts zurückgibt, wird print a.sort()None drucken.


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

Nein, weil dadurch die ursprüngliche Liste geändert wird.

8
Christian

Die Funktion .sort () speichert den Wert der neuen Liste direkt in der Listenvariablen. Die Antwort auf Ihre dritte Frage wäre also NO . Auch wenn Sie dies mithilfe von sortierter Liste (Liste) tun, können Sie es verwenden, da es nicht in der Listenvariablen gespeichert ist. Manchmal fungiert die .sort () -Methode auch als Funktion oder nimmt an, dass sie Argumente mitnimmt.

Sie müssen den Wert von Sortiert (Liste) explizit in einer Variablen speichern.

Auch für die kurze Datenverarbeitung hat die Geschwindigkeit keinen Unterschied. aber für lange Listen; Sie sollten die .sort () - Methode direkt verwenden, um schnell zu arbeiten. aber Sie werden wieder unwiderruflichen Handlungen gegenüberstehen. 

1
Vicrobot

Hinweis: Der einfachste Unterschied zwischen sort () und sort () ist: sort () liefert keinen Wert zurück, sortiert gibt eine iterierbare Liste zurück.

sort () gibt keinen Wert zurück.

Die sort () -Methode sortiert die Elemente einer bestimmten Liste in einer bestimmten Reihenfolge - aufsteigend oder absteigend, ohne einen Wert zurückzugeben.

Die Syntax der sort () -Methode lautet:

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

Alternativ können Sie auch die eingebaute Funktion von Python sortieren () .__ verwenden. für den gleichen Zweck. Sortierte Funktion gibt sortierte Liste zurück

 list=sorted(list, key=..., reverse=...)
0
Projesh Bhoumik

Hier einige einfache Beispiele, um den Unterschied in der Aktion zu sehen:

Die Liste der Nummern finden Sie hier:

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

Wenn Sie sorted in dieser Liste aufrufen, erstellt sorted eine Kopie der Liste. (Das heißt, Ihre ursprüngliche Liste bleibt unverändert.)

Mal schauen.

sorted(nums)

kehrt zurück

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

Nochmal die nums betrachten

nums

Wir sehen die ursprüngliche Liste (unverändert und NICHT sortiert). sorted hat die ursprüngliche Liste nicht geändert

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

Wenn Sie dieselbe nums-Liste verwenden und die sort-Funktion darauf anwenden, wird die aktuelle Liste geändert. 

Mal schauen.

Beginnen wir mit unserer Liste nums, um sicherzustellen, dass der Inhalt immer noch derselbe ist.

nums

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

nums.sort()

Jetzt wurde die ursprüngliche Nummernliste geändert, und wenn wir uns die Nummern ansehen, sehen wir, dass sich unsere ursprüngliche Liste geändert hat und nun sortiert ist. 

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