Warum gibt random.shuffle
None
in Python zurück?
>>> x = ['foo','bar','black','sheep']
>>> from random import shuffle
>>> print shuffle(x)
None
Wie erhalte ich den gemischten Wert anstelle von None
?
random.shuffle()
ändert die x
-Liste in Stelle.
Python-API-Methoden, die eine Struktur vor Ort ändern, geben im Allgemeinen None
zurück, nicht die geänderte Datenstruktur.
Wenn Sie eine new - zufällig gemischte Liste basierend auf einer vorhandenen Liste erstellen möchten, in der die vorhandene Liste in Reihenfolge gehalten wird, können Sie random.sample()
mit der vollen Länge der Eingabe verwenden:
x = ['foo', 'bar', 'black', 'sheep']
random.sample(x, len(x))
Sie können auch sorted()
mit random.random()
für einen Sortierschlüssel verwenden:
shuffled = sorted(x, key=lambda k: random.random())
dies ruft jedoch eine Sortierung auf (eine O(NlogN) Operation), während für das Abtasten der Eingangslänge nur O(N) Operationen benötigt werden (derselbe Prozess wie random.shuffle()
wird verwendet, um zufällig auszutauschen Werte aus einem schrumpfenden Pool).
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']
Diese Methode funktioniert auch.
import random
shuffled = random.sample(original, len(original))
Nach docs :
Mischen Sie die Sequenz x. Das optionale Argument random ist ein 0-Argument-Funktion, die einen zufälligen Float in [0.0, 1.0) zurückgibt; durch 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 vorhandene Liste. 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.
Nach dem "explizit ist besser als implizit" Prinzip von pythonischer Stil wäre es eine schlechte Idee, die Liste zurückzugeben, denn dann könnte man es denken ist neu, obwohl dies nicht der Fall ist.
Wenn Sie eine neue Liste benötigen , müssen Sie 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, verpacken Sie es in eine Funktion shuffled
(siehe sorted
), die new_x
zurückgibt.
shuffle(x)
gibt keine Werte zurück. Stattdessen mischt diese Funktion die Variable selbst.
Also versuche es nicht
print shuffle(x)
drucken Sie die Variable stattdessen einfach so aus.
>>> x = ['foo','bar','black','sheep']
>>> from random import shuffle
>>> x
['bar', 'black', 'foo', 'sheep']
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']
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]
>> x = ['foo','bar','black','sheep']
>> random.shuffle(x)
>> print(x)
>> ['sheep', 'bar', 'foo', 'black']
Wie bereits erwähnt, ersetzt random.shuffle an Ort und Stelle, sodass Sie keine neue Listenvariable benötigen.
Sie können die gemischte Liste mit random.sample()
zurückgeben, wie von anderen erläutert. Es funktioniert durch Abtasten von k Elementen aus der Liste ohne Ersetzung ..__ Wenn doppelte Elemente in Ihrer Liste vorhanden sind, werden sie 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]