Existe-t-il de meilleurs moyens de mélanger au hasard deux listes liées sans casser leur correspondance dans l'autre liste? J'ai trouvé des questions connexes dans numpy.array
et c#
mais pas exactement les mêmes.
Dans un premier temps, une astuce Zip
simple suffira:
import random
a = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]
b = [2, 4, 6, 8, 10]
c = Zip(a, b)
random.shuffle(c)
a = [e[0] for e in c]
b = [e[1] for e in c]
print a
print b
Il obtiendra le résultat:
[[1, 2], [7, 8], [3, 4], [5, 6], [9, 10]]
[2, 8, 4, 6, 10]
Trouvez-le un peu gênant. Et il faut aussi une liste supplémentaire.
Étant donné la relation illustrée dans la question, je suppose que les listes ont la même longueur et que list1[i]
correspond à list2[i]
pour tout index i
. Avec cette hypothèse en place, mélanger les listes est aussi simple que mélanger les index:
Pour Python2.x:
from random import shuffle # Given list1 and list2 list1_shuf = [] list2_shuf = [] index_shuf = range(len(list1)) shuffle(index_shuf) for i in index_shuf: list1_shuf.append(list1[i]) list2_shuf.append(list2[i])
Pour Python 3.x:
from random import shuffle # Given list1 and list2 list1_shuf = [] list2_shuf = [] index_shuf = list(range(len(list1))) shuffle(index_shuf) for i in index_shuf: list1_shuf.append(list1[i]) list2_shuf.append(list2[i])
Si vous souhaitez installer quelques paquets supplémentaires:
Demande: NumPy (> = 1.6.1), SciPy (> = 0.9).
pip installer -U scikit-learn
from sklearn.utils import shuffle
list_1, list_2 = shuffle(list_1, list_2)
Si vous devez le faire souvent, vous pouvez envisager d’ajouter un niveau d’indirection en brassant une liste d’index.
Python 2.6.6 (r266:84297, Aug 24 2010, 18:13:38) [MSC v.1500 64 bit (AMD64)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import random
>>> a = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]
>>> b = [2, 4, 6, 8, 10]
>>> indexes = range(len(a))
>>> indexes
[0, 1, 2, 3, 4]
>>> random.shuffle(indexes)
>>> indexes
[4, 1, 2, 0, 3]
>>> for index in indexes:
... print a[index], b[index]
...
[9, 10] 10
[3, 4] 4
[5, 6] 6
[1, 2] 2
[7, 8] 8
Jusqu'ici, toutes les solutions ont créé de nouvelles listes afin de résoudre le problème. Si les listes a et b sont très longues, vous pouvez les mélanger. Pour cela, vous aurez besoin d’une fonction comme:
import random
def shuffle(a,b):
assert len(a) == len(b)
start_state = random.getstate()
random.shuffle(a)
random.setstate(start_state)
random.shuffle(b)
a = [1,2,3,4,5,6,7,8,9]
b = [11,12,13,14,15,16,17,18,19]
shuffle(a,b)
print(a) # [9, 7, 3, 1, 2, 5, 4, 8, 6]
print(b) # [19, 17, 13, 11, 12, 15, 14, 18, 16]
Une réponse rapide en utilisant numpy s'il vous plaît se référer à ici :
Vous pouvez utiliser
p = numpy.random.permutation(len(a))
Pour créer une nouvelle liste d’index pour les deux listes et l’utiliser pour les réorganiser.
Dans votre scénario:
In [61]: a = [[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]]
In [62]: b = [2, 4, 6, 8, 10]
In [63]: import numpy as np
In [64]: a_ar, b_ar = np.array(a), np.array(b)
In [65]: p = np.random.permutation(len(a))
In [66]: a, b = a_ar[p].tolist(), b_ar[p].tolist()
In [68]: a
Out[68]: [[3, 4], [7, 8], [5, 6], [1, 2], [9, 10]]
In [69]: b
Out[69]: [4, 8, 6, 2, 10]
Je ne sais pas s'il me manque quelque chose ici, mais il semblerait que vous ne fassiez que brouiller l'une des listes et que l'autre soit réorganisée pour correspondre à l'ordre de la première liste. Donc, ce que vous avez est la meilleure façon de faire cela sans le rendre plus compliqué. Si vous souhaitez suivre la voie compliquée, vous pouvez simplement mélanger 1 liste et utiliser la liste non mélangée pour faire une recherche dans la liste mélangée et la réorganiser de cette manière. En fin de compte, vous obtenez le même résultat que vous avez commencé. Pourquoi la création d'une troisième liste pose-t-elle problème? Si vous voulez vraiment recycler les listes, vous pouvez simplement remplacer la liste b par ce que vous utilisez pour la liste c, puis la séparer plus tard en a et b.