133 votes

Pourquoi random.shuffle renvoie-t-il None ?

Pourquoi est-ce que random.shuffle en retournant sur None en Python ?

>>> x = ['foo','bar','black','sheep']
>>> from random import shuffle
>>> print shuffle(x)
None

Comment puis-je obtenir la valeur mélangée au lieu de None ?

219voto

Martijn Pieters Points 271458

random.shuffle() modifie le x liste en place .

Les méthodes de l'API Python qui modifient une structure en place retournent généralement None et non la structure de données modifiée.

>>> x = ['foo', 'bar', 'black', 'sheep']
>>> random.shuffle(x)
>>> x
['black', 'bar', 'sheep', 'foo']

Si vous vouliez créer un nouveau pour créer une liste mélangée de façon aléatoire à partir d'une liste existante, en conservant l'ordre de la liste existante, vous pouvez utiliser la fonction random.sample() avec toute la longueur de l'entrée :

random.sample(x, len(x))     

Vous pouvez également utiliser sorted() con random.random() pour une clé de tri :

shuffled = sorted(x, key=lambda k: random.random())

mais cela implique un tri (une opération O(N log N)), alors que l'échantillonnage à la longueur de l'entrée ne prend que O(N) opérations (le même processus que random.shuffle() est utilisé, en échangeant des valeurs aléatoires à partir d'un pool qui se réduit).

Démonstration :

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

48voto

Acemad Points 2761

Cette méthode fonctionne aussi.

import random
shuffled = random.sample(original, len(original))

11voto

Lutz Prechelt Points 470

Pourquoi, vraiment ?

1. Efficacité

shuffle modifie la liste en place. C'est une bonne chose, car la copie d'une grande liste serait une pure surcharge si vous n'avez plus besoin de la liste originale.

2. Le style pythonique

Selon le "l'explicite est meilleur que l'implicite" principe de style pythonique le fait de renvoyer la liste serait une mauvaise idée, car on pourrait alors penser qu'elle est un nouveau, alors qu'en fait, il ne l'est pas.

Mais je n'aime pas ça comme ça !

Si vous faire vous avez besoin d'une nouvelle liste, vous devrez écrire quelque chose comme

new_x = list(x)  # make a copy
random.shuffle(new_x)

ce qui est joliment explicite. Si vous avez souvent besoin de cet idiome, intégrez-le dans une fonction shuffled (voir sorted ) qui renvoie new_x .

7voto

alecxe Points 50783

Selon docs :

Mélangez la séquence x en place. L'argument facultatif random est un fonction à 0 argument retournant un flottant aléatoire dans [0.0, 1.0) ; par par défaut, il s'agit de la fonction random().

x = ['foo','bar','black','sheep'] from random import shuffle shuffle(x) x ['bar', 'black', 'sheep', 'foo']

2voto

user3680588 Points 72

J'ai eu mon moment "aha" avec ce concept comme ceci :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X