2012-08-01 26 views
22

¿Hay mejores formas de mezclar aleatoriamente dos listas relacionadas sin romper su correspondencia en la otra lista? He encontrado preguntas relacionadas en numpy.array y c#, pero no exactamente la misma.Mejor forma de mezclar dos listas relacionadas

Como primer intento, un simple truco zip hará:

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 

Se obtendrá la salida:

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

Sólo tiene que encontrar un poco incómodo. Y también necesita una lista adicional también.

+5

puede usar 'zip' para descomprimir las listas, así:' a, b = zip (* c) ' – mgilson

+3

que sería también, en general, no recomendar un programa diseño donde necesita mantener un conjunto de listas paralelas. Solo mantén 1 lista. Crea algún tipo de clase o algo para unificar tus datos. – mgilson

+0

Si uno quiere hacer tal trabajo por 'numpy', aquí hay una buena solución: http: //stackoverflow.com/questions/4601373/better-way-to-shuffle-two-numpy-arrays-in-unison – Mithril

Respuesta

35

Dada la relación demostrada en la pregunta, voy a suponer que las listas son de la misma longitud y que list1[i] corresponde a list2[i] para cualquier índice i. Con esa suposición en su lugar, arrastrando las listas es tan simple como arrastrar los pies de los índices:

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]) 
+9

As un seguidor de listas de comprensión: list1_shuf = [list1 [i] for i en index_shuf] –

+1

@kojiro: no importa: n * append_ops + n * append_ops = n * (append_ops + append_ops) = 2 * n * append_ops – Lazik

5

Si usted tiene que hacer esto a menudo, usted podría considerar la adición de un nivel de indirección barajando una lista de índices.

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 
0

No estoy seguro de si estoy perdiendo algo, pero parece que sólo está barajando 1 de las listas y el otro es reorganizado para que coincida con el orden de la primera lista. Entonces, lo que tienes es la mejor manera de hacerlo sin complicarlo más. Si desea ir por la ruta complicada, puede simplemente mezclar 1 lista y usar la lista no procesada para realizar una búsqueda en la lista mezclada y reorganizarla de esa manera. Al final terminas con el mismo resultado con el que comenzaste. ¿Por qué crear una tercera lista es un problema? Si realmente desea reciclar las listas, puede simplemente reemplazar la lista b con la que está usando para la lista c y luego separarla más adelante de nuevo a ay b.

1

Una respuesta rápida usando numpy consulte here:
Usted puede utilizar

p = numpy.random.permutation(len(a)) 

Para crear una nueva lista de índices de ambas listas y utilizarlo para cambiar su orden.

En su escenario:

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

Si usted está dispuesto a instalar unos cuantos paquetes:

Req: NumPy (> = 1.6.1), SciPy (> = 0.9).

pip instalación -U scikit-learn

from sklearn.utils import shuffle 
list_1, list_2 = shuffle(list_1, list_2) 
Cuestiones relacionadas