随机化两个列表并在python中维护顺序

时间:2012-11-12 12:01:09

标签: python

说我有两个简单的清单,

a = ['Spears', "Adele", "NDubz", "Nicole", "Cristina"]
b = [1,2,3,4,5]
len(a) == len(b)

我想做的是随机ab,但要保持顺序。所以,像:

a = ["Adele", 'Spears', "Nicole", "Cristina", "NDubz"]
b = [2,1,4,5,3]

我知道我可以使用以下方式对一个列表进行洗牌:

import random
random.shuffle(a)

但这只是随机化a,而我想随机化a,并在列表b中维护“随机顺序”。

非常感谢有关如何实现这一目标的任何指导。

7 个答案:

答案 0 :(得分:74)

我将两个列表组合在一起,将结果列表混合,然后拆分它们。这使用zip()

a = ["Spears", "Adele", "NDubz", "Nicole", "Cristina"]
b = [1, 2, 3, 4, 5]

combined = list(zip(a, b))
random.shuffle(combined)

a[:], b[:] = zip(*combined)

答案 1 :(得分:14)

使用具有漂亮功能的zip以“两种”方式工作。

import random

a = ['Spears', "Adele", "NDubz", "Nicole", "Cristina"]
b = [1,2,3,4,5]
z = zip(a, b)
# => [('Spears', 1), ('Adele', 2), ('NDubz', 3), ('Nicole', 4), ('Cristina', 5)]
random.shuffle(z)
a, b = zip(*z)

答案 2 :(得分:8)

要避免重新发明轮子,请使用sklearn

from sklearn.utils import shuffle

a, b = shuffle(a, b)

答案 3 :(得分:7)

请注意,Tim的答案仅适用于Python 2,而不适用于Python 3.如果使用Python 3,则需要执行以下操作:

combined = list(zip(a, b))
random.shuffle(combined)
a[:], b[:] = zip(*combined)

否则你会收到错误:

TypeError: object of type 'zip' has no len()

答案 4 :(得分:2)

另一种方式可能是

a = ['Spears', "Adele", "NDubz", "Nicole", "Cristina"]
b = range(len(a)) # -> [0, 1, 2, 3, 4]
b_alternative = range(1, len(a) + 1) # -> [1, 2, 3, 4, 5]
random.shuffle(b)
a_shuffled = [a[i] for i in b] # or:
a_shuffled = [a[i - 1] for i in b_alternative]

这是相反的方法,但可以帮助你。

答案 5 :(得分:0)

这是我的方式:

import random
def shuffleTogether(A, B):
    if len(A) != len(B):
        raise Exception("Lengths don't match")
    indexes = range(len(A))
    random.shuffle(indexes)
    A_shuffled = [A[i] for i in indexes]    
    B_shuffled = [B[i] for i in indexes]
    return A_shuffled, B_shuffled

A = ['a', 'b', 'c', 'd']
B = ['1', '2', '3', '4']
A_shuffled, B_shuffled = shuffleTogether(A, B)
print A_shuffled
print B_shuffled

答案 6 :(得分:0)

有一种更简单的方法可以避免压缩,复制以及所有繁重的工作。我们可以分别将它们两者都洗牌,但是两次都使用相同的种子,这保证了洗牌的顺序是相同的。

import random as rd

A = list("abcde")
B = list(range(len(A)))
fixed_seed = rd.random()
rd.Random(fixed_seed).shuffle(A)
rd.Random(fixed_seed).shuffle(B)

A和B分别是:

['e', 'a', 'c', 'b', 'd']
[ 4,   0,   2,   1,   3]

更通用的版本,用于任意数量的列表:

def shuffle(*xss):
    seed = rd.random()
    for xs in xss:
        rd.Random(seed).shuffle(xs)