2012-08-01 43 views
22

有没有更好的方法来随机洗牌两个相关的列表,而不会破坏其他列表中的通信?我在numpy.arrayc#中发现了相关的问题,但不完全一样。更好的方式来洗牌两个相关的列表

作为第一次尝试,一个简单的zip招会做:

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 

它会得到输出:

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

只是觉得有点别扭。而且它也需要一个额外的列表。

+5

您可以用'zip'解压名单,以及:'A,B = ZIP(* C)' – mgilson 2012-08-01 18:16:07

+3

我也一般不推荐方案设计你需要保留一组平行列表的地方。只保留1个列表。创建某种类或某些内容来统一数据。 – mgilson 2012-08-01 18:19:02

+0

如果你想用'numpy'做这样的工作,这里是一个很好的解决方案:http://stackoverflow.com/questions/4601373/better-way-to-shuffle-two-numpy-arrays-in-unison – Mithril 2016-04-14 08:24:58

回答

35

鉴于问题中显示的关系,我将假定列表长度相同,并且对于任何索引ilist1[i]对应于list2[i]。有了这样的假设,洗牌的名单是洗牌的指标简单:

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列表解析迷:list1_shuf = [list1 [i] for index_shuf] – 2013-11-02 17:06:52

+1

@kojiro:无关紧要:n * append_ops + n * append_ops = n *(append_ops + append_ops)= 2 * n * append_ops – Lazik 2013-12-12 14:01:43

5

如果你经常这样做,你可以考虑通过改组索引的列表中添加一个间接层。

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

我不知道如果我失去了一些东西,但它看起来像你只是洗牌的名单1,另一种是重新排列,以匹配第一个列表的顺序。所以你有什么是最好的方法来做到这一点,而不是更复杂。如果你想要去复杂的路线,你可以洗个清单,然后使用非混洗列表在混洗列表中进行查找并以这种方式重新排列它。最后,你最终会得到和你一样的结果。为什么要创建第三个列表是一个问题?如果你真的想要回收这些列表,那么你可以简单地用列表c替换列表c中的内容,然后再将它分离回a和b。

1

使用numpy的,请参阅here快速回答:
您可以使用

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

创建索引的两个表一个新的列表,并使用它来重新排序。

在您的方案:

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

如果你愿意安装其他软件包:

所需物品: NumPy的(> = 1.6.1), SciPy的(> = 0.9)。

PIP安装-U scikit学习

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