Question Mélanger une liste d'objets


J'ai une liste d'objets en Python et je veux les mélanger. Je pensais pouvoir utiliser le random.shuffle méthode, mais cela semble échouer lorsque la liste est des objets. Existe-t-il une méthode pour mélanger l'objet ou une autre façon de contourner cela?

import random

class a:
    foo = "bar"

a1 = a()
a2 = a()
b = [a1,a2]

print random.shuffle(b)

Cela échouera.


519
2018-06-10 16:56


origine


Réponses:


random.shuffle devrait marcher. 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 le mélange fonctionne en placeet renvoie Aucun.


857
2018-06-10 17:03



Comme vous avez appris le brassage en place était le problème. J'ai aussi souvent des problèmes, et j'ai souvent l'impression d'oublier comment copier une liste aussi. En utilisant sample(a, len(a)) est la solution, en utilisant len(a) comme la taille de l'échantillon. Voir https://docs.python.org/3.6/library/random.html#random.sample pour la documentation Python.

Voici une version simple utilisant random.sample() Cela retourne le résultat mélangé comme 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

88
2017-10-19 16:50



Il m'a fallu du temps pour l'obtenir aussi. Mais la documentation pour shuffle est très claire:

liste de lecture aléatoire x en place; retourner Aucun.

Donc tu ne devrais pas print random.shuffle(b). Au lieu de faire random.shuffle(b) et alors print b.


31
2017-11-21 14:49



#!/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]

30
2017-12-04 12:46



>>> 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.


19
2018-06-10 17:04



Si vous utilisez déjà Numpy (très populaire pour les applications scientifiques et financières), vous pouvez vous enregistrer une importation.

import numpy as np    
np.random.shuffle(b)
print(b)

http://docs.scipy.org/doc/numpy/reference/generated/numpy.random.shuffle.html


16
2018-02-28 02:35



Si vous avez plusieurs listes, vous pouvez d'abord définir la permutation (la façon dont vous mélangez la liste / réorganiser les éléments de la liste), puis l'appliquer à 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]

Numpy / Scipy

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]

mpu

J'ai créé le petit paquet utilitaire mpu qui a le consistent_shuffle fonction:

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. Vous pouvez donc également mélanger trois listes ou plus avec elle.


8
2018-02-05 16:15



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 voulez échanger la fonction de commande.


6
2018-05-06 00:04



'print func (foo)' affichera la valeur de retour de 'func' lorsqu'il est appelé avec 'foo'. 'shuffle' a cependant None comme type de retour, car la liste sera modifiée en place, donc elle n'imprime rien. Solution de contournement:

# shuffle the list in place 
random.shuffle(b)

# print it
print(b)

Si vous préférez le style de programmation fonctionnelle, vous pouvez utiliser la fonction d'encapsulation suivante:

def myshuffle(ls):
    random.shuffle(ls)
    return ls

5
2018-05-24 14:59



Dans certains cas, lorsque vous utilisez des tableaux numpy, en utilisant random.shuffle créé des données en double dans le tableau.

Une alternative est d'utiliser numpy.random.shuffle. Si vous travaillez déjà avec numpy, c'est la méthode préférée par rapport au générique random.shuffle.

numpy.random.shuffle

Exemple

>>> import numpy as np
>>> import random

En utilisant 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]])

En utilisant 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]])

4
2017-12-19 17:01



On peut définir une fonction appelée shuffled (dans le même sens de sort contre sorted)

def shuffled(x):
    import random
    y = x[:]
    random.shuffle(y)
    return y

x = shuffled([1, 2, 3, 4])
print x

2
2018-05-06 00:48