2012-08-01 77 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)