J'ai une liste d'objets dans Python et je veux les mélanger. Je pensais pouvoir utiliser la méthode random.shuffle
, mais cela semble échouer lorsque la liste est constituée d'objets. Existe-t-il une méthode pour mélanger les objets ou une autre manière de contourner cela?
import random
class a:
foo = "bar"
a1 = a()
a2 = a()
b = [a1,a2]
print random.shuffle(b)
Cela va échouer.
random.shuffle
devrait fonctionner. Voici un exemple où les objets sont des listes:
_from random import shuffle
x = [[i] for i in range(10)]
shuffle(x)
# print x gives [[9], [2], [7], [0], [4], [5], [3], [1], [8], [6]]
# of course your results will vary
_
Notez que shuffle fonctionne à la place et renvoie Aucun.
Comme vous l'avez appris, le problème était le brassage sur place. J'ai aussi souvent des problèmes et semble souvent oublier comment copier une liste. Utiliser sample(a, len(a))
est la solution, en utilisant len(a)
comme taille d’échantillon. Voir https://docs.python.org/3.6/library/random.html#random.sample pour la documentation Python.
Voici une version simple utilisant random.sample()
qui renvoie le résultat mélangé sous la forme d'une nouvelle liste.
import random
a = range(5)
b = random.sample(a, len(a))
print a, b, "two list same:", a == b
# print: [0, 1, 2, 3, 4] [2, 1, 3, 4, 0] two list same: False
# The function sample allows no duplicates.
# Result can be smaller but not larger than the input.
a = range(555)
b = random.sample(a, len(a))
print "no duplicates:", a == list(set(b))
try:
random.sample(a, len(a) + 1)
except ValueError as e:
print "Nope!", e
# print: no duplicates: True
# print: Nope! sample larger than population
Cela m'a pris du temps pour l'obtenir aussi. Mais la documentation pour shuffle est très claire:
liste aléatoire x en place; retourner Aucun.
Donc, vous ne devriez pas print random.shuffle(b)
. À la place, faites random.shuffle(b)
puis print b
.
#!/usr/bin/python3
import random
s=list(range(5))
random.shuffle(s) # << shuffle before print or assignment
print(s)
# print: [2, 4, 1, 3, 0]
Si vous utilisez déjà numpy (très populaire pour les applications scientifiques et financières), vous pouvez économiser une importation.
import numpy as np
np.random.shuffle(b)
print(b)
http://docs.scipy.org/doc/numpy/reference/generated/numpy.random.shuffle.html
>>> import random
>>> a = ['hi','world','cat','dog']
>>> random.shuffle(a,random.random)
>>> a
['hi', 'cat', 'dog', 'world']
Ça fonctionne bien pour moi. Assurez-vous de définir la méthode aléatoire.
Si vous avez plusieurs listes, vous pouvez commencer par définir la permutation (la façon dont vous mélangez/réorganisez les éléments de la liste) puis appliquez-la à toutes les listes:
_import random
perm = list(range(len(list_one)))
random.shuffle(perm)
list_one = [list_one[index] for index in perm]
list_two = [list_two[index] for index in perm]
_
Si vos listes sont des tableaux numpy, c'est plus simple:
_import numpy as np
perm = np.random.permutation(len(list_one))
list_one = list_one[perm]
list_two = list_two[perm]
_
J'ai créé le petit paquet utilitaire mpu
qui a la fonction consistent_shuffle
:
_import mpu
# Necessary if you want consistent results
import random
random.seed(8)
# Define example lists
list_one = [1,2,3]
list_two = ['a', 'b', 'c']
# Call the function
list_one, list_two = mpu.consistent_shuffle(list_one, list_two)
_
Notez que _mpu.consistent_shuffle
_ prend un nombre arbitraire d'arguments. Ainsi, vous pouvez également mélanger trois listes ou plus avec elle.
from random import random
my_list = range(10)
shuffled_list = sorted(my_list, key=lambda x: random())
Cette alternative peut être utile pour certaines applications où vous souhaitez échanger la fonction de commande.
Dans certains cas, lors de l'utilisation de tableaux numpy, l'utilisation de random.shuffle
créait des données en double dans le tableau.
Une alternative consiste à utiliser numpy.random.shuffle
. Si vous travaillez déjà avec numpy, cette méthode est préférable au générique random.shuffle
.
Exemple
>>> import numpy as np
>>> import random
Utiliser random.shuffle
:
>>> foo = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> foo
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
>>> random.shuffle(foo)
>>> foo
array([[1, 2, 3],
[1, 2, 3],
[4, 5, 6]])
Utiliser numpy.random.shuffle
:
>>> foo = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> foo
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
>>> np.random.shuffle(foo)
>>> foo
array([[1, 2, 3],
[7, 8, 9],
[4, 5, 6]])
'print func (foo)' affichera la valeur de retour de 'func' lorsqu'il sera appelé avec 'foo'. 'shuffle' a toutefois la valeur None comme type de retour, car la liste sera modifiée à la place, elle n'imprimera donc rien. Solution de contournement:
# shuffle the list in place
random.shuffle(b)
# print it
print(b)
Si vous êtes plus dans le style de programmation fonctionnelle, vous voudrez peut-être créer la fonction wrapper suivante:
def myshuffle(ls):
random.shuffle(ls)
return ls
On peut définir une fonction appelée shuffled
(dans le même sens que sort
vs sorted
)
def shuffled(x):
import random
y = x[:]
random.shuffle(y)
return y
x = shuffled([1, 2, 3, 4])
print x
Pour les one-liners, utilisezrandom.sample(list_to_be_shuffled, length_of_the_list)
avec un exemple:
import random
random.sample(list(range(10)), 10)
sorties: [2, 9, 7, 8, 3, 0, 4, 1, 6, 5]
import random
class a:
foo = "bar"
a1 = a()
a2 = a()
a3 = a()
a4 = a()
b = [a1,a2,a3,a4]
random.shuffle(b)
print(b)
shuffle
est en place, donc n'imprimez pas le résultat, qui est None
, mais la liste.
vous pouvez créer une fonction qui prend une liste en tant que paramètre et renvoie une version aléatoire de la liste:
from random import *
def listshuffler(inputlist):
for i in range(len(inputlist)):
swap = randint(0,len(inputlist)-1)
temp = inputlist[swap]
inputlist[swap] = inputlist[i]
inputlist[i] = temp
return inputlist
def shuffle(_list):
if not _list == []:
import random
list2 = []
while _list != []:
card = random.choice(_list)
_list.remove(card)
list2.append(card)
while list2 != []:
card1 = list2[0]
list2.remove(card1)
_list.append(card1)
return _list
Vous pouvez y aller pour ça:
>>> A = ['r','a','n','d','o','m']
>>> B = [1,2,3,4,5,6]
>>> import random
>>> random.sample(A+B, len(A+B))
[3, 'r', 4, 'n', 6, 5, 'm', 2, 1, 'a', 'o', 'd']
si vous souhaitez revenir à deux listes, vous divisez cette longue liste en deux.
Assurez-vous de ne pas nommer votre fichier source random.py et qu'il n'y a pas de fichier dans votre répertoire de travail appelé random.pyc. .
""" to shuffle random, set random= True """
def shuffle(x,random=False):
shuffled = []
ma = x
if random == True:
rando = [ma[i] for i in np.random.randint(0,len(ma),len(ma))]
return rando
if random == False:
for i in range(len(ma)):
ave = len(ma)//3
if i < ave:
shuffled.append(ma[i+ave])
else:
shuffled.append(ma[i-ave])
return shuffled
import random
class a:
foo = "bar"
a1 = a()
a2 = a()
b = [a1.foo,a2.foo]
random.shuffle(b)
vous pouvez utiliser shuffle ou sample. qui viennent tous deux du module aléatoire.
import random
def shuffle(arr1):
n=len(arr1)
b=random.sample(arr1,n)
return b
OR
import random
def shuffle(arr1):
random.shuffle(arr1)
return arr1