56

Say I have two simple lists,

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

What I would like to do is randomize a and b but maintain the order. So, something like:

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

I am aware that I can shuffle one list using:

import random
random.shuffle(a)

But this just randomizes a, whereas, I would like to randomize a, and maintain the "randomized order" in list b.

Would appreciate any guidance on how this can be achieved.

4

7 回答 7

89

我会将这两个列表组合在一起,将结果列表打乱,然后拆分它们。这利用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)
于 2012-11-12T12:04:00.197 回答
19

使用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)
于 2012-11-12T12:04:09.670 回答
18

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

from sklearn.utils import shuffle

a, b = shuffle(a, b)
于 2018-05-14T12:13:43.883 回答
10

请注意,蒂姆的答案仅适用于 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()
于 2015-05-18T02:46:55.447 回答
3

有一种更简单的方法可以避免压缩、复制和所有繁重的东西。我们可以分别对它们进行洗牌,但两次都使用相同的种子,这样可以保证洗牌的顺序是相同的。

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)
于 2019-11-14T10:17:42.303 回答
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]

这是相反的方法,但仍然可以帮助您。

于 2012-11-12T12:11:19.620 回答
1

这是我的风格:

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
于 2018-01-27T16:36:55.643 回答