random.shuffle()ändert die xListe an Ort und Stelle .
Python-API-Methoden, die eine Struktur direkt ändern, geben im Allgemeinen Nonenicht die geänderte Datenstruktur zurück.
Wenn Sie eine neue zufällig gemischte Liste basierend auf einer vorhandenen Liste erstellen möchten, in der die vorhandene Liste in der richtigen Reihenfolge gehalten wird, können Sie sie random.sample()mit der gesamten Länge der Eingabe verwenden:
x = ['foo', 'bar', 'black', 'sheep']
random.sample(x, len(x))
Dies ruft jedoch die Sortierung auf (eine O (NlogN) -Operation), während das Abtasten auf die Eingabelänge nur O (N) -Operationen erfordert (der gleiche Prozess wie random.shuffle()der, bei dem zufällige Werte aus einem schrumpfenden Pool ausgetauscht werden).
Ist die Verwendung einer zufällig bewerteten keyFunktion wirklich garantiert? Einige schnelle Sortieralgorithmen fallen um, wenn Vergleiche nicht selbstkonsistent sind. Ich kann sehen, dass dies je nach Implementierung in beide Richtungen funktioniert (Decorate-Sort-Undecorate muss nur keyeinmal auf jedes Element angewendet werden, damit es genau definiert ist).
Torek
2
@torek: Python verwendet beim Sortieren mit einem keyaufrufbaren Element dekorieren-sortieren-undekorieren . Also ja, es ist garantiert, da jeder Wert genau einmal seinen Zufallsschlüssel erhält.
Martijn Pieters
35
Diese Methode funktioniert auch.
import random
shuffled = random.sample(original, len(original))
Mische die Sequenz x an Ort und Stelle. Das optionale Argument random ist eine 0-Argument-Funktion, die einen zufälligen Float in [0.0, 1.0) zurückgibt. Standardmäßig ist dies die Funktion random ().
>>> x = ['foo','bar','black','sheep']
>>> from random import shuffle
>>> shuffle(x)
>>> x
['bar', 'black', 'sheep', 'foo']
shuffleändert die Liste an Ort und Stelle. Das ist schön, denn das Kopieren einer großen Liste wäre ein reiner Aufwand, wenn Sie die ursprüngliche Liste nicht mehr benötigen.
2. Pythonischer Stil
Nach dem Prinzip "explizit ist besser als implizit" des pythonischen Stils wäre es eine schlechte Idee, die Liste zurückzugeben, da man dann denken könnte, es sei eine neue, obwohl dies tatsächlich nicht der Fall ist.
Aber ich mag es nicht so!
Wenn Sie noch eine frische Liste benötigen, haben Sie so etwas wie schreiben
new_x = list(x) # make a copy
random.shuffle(new_x)
das ist schön explizit. Wenn Sie dieses Idiom häufig benötigen, schließen Sie es in eine Funktion shuffled(siehe sorted) ein, die zurückgibt new_x.
Sie können die gemischte Liste random.sample()wie von anderen erläutert zurückgeben. Es funktioniert, indem k Elemente aus der Liste ersatzlos abgetastet werden . Wenn Ihre Liste also doppelte Elemente enthält, werden diese eindeutig behandelt.
Antworten:
random.shuffle()
ändert diex
Liste an Ort und Stelle .Python-API-Methoden, die eine Struktur direkt ändern, geben im Allgemeinen
None
nicht die geänderte Datenstruktur zurück.Wenn Sie eine neue zufällig gemischte Liste basierend auf einer vorhandenen Liste erstellen möchten, in der die vorhandene Liste in der richtigen Reihenfolge gehalten wird, können Sie sie
random.sample()
mit der gesamten Länge der Eingabe verwenden:x = ['foo', 'bar', 'black', 'sheep'] random.sample(x, len(x))
Sie können auch
sorted()
mitrandom.random()
für einen Sortierschlüssel verwenden:shuffled = sorted(x, key=lambda k: random.random())
Dies ruft jedoch die Sortierung auf (eine O (NlogN) -Operation), während das Abtasten auf die Eingabelänge nur O (N) -Operationen erfordert (der gleiche Prozess wie
random.shuffle()
der, bei dem zufällige Werte aus einem schrumpfenden Pool ausgetauscht werden).Demo:
>>> import random >>> x = ['foo', 'bar', 'black', 'sheep'] >>> random.sample(x, len(x)) ['bar', 'sheep', 'black', 'foo'] >>> sorted(x, key=lambda k: random.random()) ['sheep', 'foo', 'black', 'bar'] >>> x ['foo', 'bar', 'black', 'sheep']
quelle
key
Funktion wirklich garantiert? Einige schnelle Sortieralgorithmen fallen um, wenn Vergleiche nicht selbstkonsistent sind. Ich kann sehen, dass dies je nach Implementierung in beide Richtungen funktioniert (Decorate-Sort-Undecorate muss nurkey
einmal auf jedes Element angewendet werden, damit es genau definiert ist).key
aufrufbaren Element dekorieren-sortieren-undekorieren . Also ja, es ist garantiert, da jeder Wert genau einmal seinen Zufallsschlüssel erhält.Diese Methode funktioniert auch.
import random shuffled = random.sample(original, len(original))
quelle
Laut Dokumentation :
>>> x = ['foo','bar','black','sheep'] >>> from random import shuffle >>> shuffle(x) >>> x ['bar', 'black', 'sheep', 'foo']
quelle
Warum eigentlich?
1. Effizienz
shuffle
ändert die Liste an Ort und Stelle. Das ist schön, denn das Kopieren einer großen Liste wäre ein reiner Aufwand, wenn Sie die ursprüngliche Liste nicht mehr benötigen.2. Pythonischer Stil
Nach dem Prinzip "explizit ist besser als implizit" des pythonischen Stils wäre es eine schlechte Idee, die Liste zurückzugeben, da man dann denken könnte, es sei eine neue, obwohl dies tatsächlich nicht der Fall ist.
Aber ich mag es nicht so!
Wenn Sie noch eine frische Liste benötigen, haben Sie so etwas wie schreiben
new_x = list(x) # make a copy random.shuffle(new_x)
das ist schön explizit. Wenn Sie dieses Idiom häufig benötigen, schließen Sie es in eine Funktion
shuffled
(siehesorted
) ein, die zurückgibtnew_x
.quelle
Ich hatte meinen Aha-Moment mit diesem Konzept wie folgt:
from random import shuffle x = ['foo','black','sheep'] #original list y = list(x) # an independent copy of the original for i in range(5): print shuffle(y) # shuffles the original "in place" prints "None" return print x,y #prints original, and shuffled independent copy >>> None ['foo', 'black', 'sheep'] ['foo', 'black', 'sheep'] None ['foo', 'black', 'sheep'] ['black', 'foo', 'sheep'] None ['foo', 'black', 'sheep'] ['sheep', 'black', 'foo'] None ['foo', 'black', 'sheep'] ['black', 'foo', 'sheep'] None ['foo', 'black', 'sheep'] ['sheep', 'black', 'foo']
quelle
Python-APIs, die die Struktur selbst ändern, geben None als Ausgabe zurück.
list = [1,2,3,4,5,6,7,8] print(list)
Ausgabe: [1, 2, 3, 4, 5, 6, 7, 8]
from random import shuffle print(shuffle(list))
Ausgabe: Keine
from random import sample print(sample(list, len(list)))
Ausgabe: [7, 3, 2, 4, 5, 6, 1, 8]
quelle
Sie können die gemischte Liste
random.sample()
wie von anderen erläutert zurückgeben. Es funktioniert, indem k Elemente aus der Liste ersatzlos abgetastet werden . Wenn Ihre Liste also doppelte Elemente enthält, werden diese eindeutig behandelt.>>> l = [1,4,5,3,5] >>> random.sample(l,len(l)) [4, 5, 5, 3, 1] >>> random.sample(l,len(l)-1) [4, 1, 5, 3] >>> random.sample(l,len(l)-1) [3, 5, 5, 1]
quelle