Meilleure façon de mélanger deux listes connexes

Existe-t-il de meilleurs moyens de mélanger aléatoirement deux listes associées sans casser leur correspondance dans l'autre liste? J'ai trouvé des questions connexes dans numpy.array et c# mais pas exactement la même.

Comme premier essai, un simple truc zip fera l'affaire:

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 la sortie:

[[1, 2], [7, 8], [3, 4], [5, 6], [9, 10]]
[2, 8, 4, 6, 10]

Trouve ça un peu gênant. Et il a également besoin d'une liste supplémentaire.

26
demandé sur clwen 2012-08-01 22:10:21

6 réponses

Compte tenu de la relation démontrée dans la question, je vais supposer 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 indices:

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])
37
répondu kojiro 2012-08-01 18:15:54

Si vous souhaitez installer quelques paquets supplémentaires:

Req: NumPy (>=1.6.1), SciPy (>=0,9).

Pip install-U scikit-learn

from sklearn.utils import shuffle
list_1, list_2 = shuffle(list_1, list_2)
17
répondu Tihomir Nedev 2017-01-14 10:47:21

Si vous avez à le faire souvent, vous pourriez envisager d'ajouter un niveau d'indirection en mélangeant 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
5
répondu Jeremy Brown 2012-08-01 18:16:48

Une réponse rapide en utilisant numpy veuillez vous 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]
1
répondu Ryszard Cetnarski 2017-11-28 15:18:40

Jusqu'à présent, toutes les solutions ont créé de nouvelles listes afin de résoudre le problème. Si la liste un et b sont très long, vous pouvez les mélanger à la place. Pour cela, vous auriez 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 = [10,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]
1
répondu AlexConfused 2018-04-17 16:45:46

Je ne suis pas sûr de manquer quelque chose ici, mais il semble que vous ne fassiez que mélanger 1 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 le faire sans le rendre plus compliqué. Si vous voulez suivre la route compliquée, vous pouvez simplement mélanger la liste 1 et utiliser la liste non brouillée pour faire une recherche dans la liste mélangée et la réorganiser de cette façon. En fin de compte, vous vous retrouvez avec le même résultat que vous avez commencé avec. Pourquoi la création d'un troisième liste un 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.

0
répondu minhaz1 2012-08-01 18:17:29