如何在Python中对多维列表进行洗牌

3

我知道如何使用随机库中的shuffle函数来打乱Python中简单的List shuffle(myList)

但是,我如何打乱多维列表?

myList[][]

shuffle(myList) 没有起作用。


1
“没起作用”是指……? - khelwood
你想要所有的维度都独立地混洗吗? - Victory
@Victory 是的,我希望所有维度都能独立地被洗牌。 - Marlon C. Carrillo
2
Numpy.random.shuffle 可能与 reshape 结合使用。 - Paul
3
只需循环遍历并在原地随机打乱每个元素?for el in myList: shuffle(el) - Jon Clements
你的意思是只洗牌单个子列表,还是将项目在子列表之间移动的(平坦)洗牌?一些答案将其解释为前者,一些则解释为后者。我们应该假设子列表具有统一的长度,还是也要处理不规则的情况?如果您发布样本输入和输出,那将会非常有帮助。 - smci
4个回答

2

您需要对顶级列表进行洗牌,然后才能在Python 2中将shuffle函数映射到子列表中,如下所示:

from random import shuffle 

foo = []
foo.append([1, 2, 3])
foo.append([4, 5, 6])
foo.append([7, 8, 9])

shuffle(foo)
map(shuffle, foo)

print foo

查看 Python 2 的 Fiddle

Python 3 中类似的操作:

from random import shuffle 

foo = []
foo.append([1, 2, 3])
foo.append([4, 5, 6])
foo.append([7, 8, 9])

shuffle(foo)
for ii, sublist in enumerate(foo): 
    shuffle(foo[ii])

print(foo)

查看Python 3的fiddle


2
@Marcin 如果使用for u in foo: shuffle(u)而不是map,它将在Python 3中正常工作。 - user1220978
1
这不是真正的洗牌,因为每一行始终都会对齐(例如[1,3,2])。你永远不会得到[1,2,5]。 - Conchylicultor
根据使用情况,这可能是预期的行为。 - Tobias Uhmann

1

使用仅限标准包,我所能想到的最有效的方法是将数组展开为单个列表,进行洗牌,然后再重新调整为列表的形式。

import random

def shuffle2d(arr2d, rand=random):
    """Shuffes entries of 2-d array arr2d, preserving shape."""
    reshape = []
    data = []
    iend = 0
    for row in arr2d:
        data.extend(row)
        istart, iend = iend, iend+len(row)
        reshape.append((istart, iend))
    rand.shuffle(data)
    return [data[istart:iend] for (istart,iend) in reshape]

def show(arr2d):
    """Shows rows of matrix (of strings) as space-separated rows."""
    print ("\n".join(" ".join(row) for row in arr2d))

# Generate some ragged data (5 rows):

arr2d = []
for i,a in enumerate("ABCDE"):
    n = random.randint(3,7)
    arr2d.append([a+str(j) for j in range(1,n+1)])

# display original and shuffled data

print ("Original...")
show(arr2d)
print ("Shuffled...")
show(shuffle2d(arr2d))
print ("Again...")
show(shuffle2d(arr2d))

样例输出(Python 2.7):

Original...
A1 A2 A3
B1 B2 B3 B4 B5
C1 C2 C3
D1 D2 D3
E1 E2 E3 E4 E5
Shuffled...
A3 C1 E5
C3 D3 A2 E1 D1
A1 E2 C2
B5 B4 B2
B1 D2 E4 E3 B3
Again...
B2 C2 C3
B1 D2 E5 A3 D1
A1 E3 A2
B5 D3 C1
B4 E4 E1 B3 E2

顺便提一下,上述内容同样适用于Python 3.4。唯一与版本有关的代码特征是print和range,它们被不加区分地使用。

0

首先,导入 numpy 模块:

import numpy as np

numpy有一个名为random.shuffle()的方法。该方法允许您对多维列表进行洗牌。

要使用此方法对列表进行洗牌,您需要将列表转换为ndarray类,然后将其传递给random.shuffle()

>>> foo = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> foo = np.array(foo)
>>> foo
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])

现在,将它洗牌。

foo = np.random.shuffle(foo)

foo的值将会是这样的:

array([[1, 2, 3],
       [7, 8, 9],
       [4, 5, 6]])

0

我在尝试随机问题和答案,同时保持2D列表中的匹配时遇到了这个问题。在撰写这篇文章时,我只学习Python三周。我的初学者解决方案是创建一个随机数,然后使用该数字从列表中选择:

a_list = [["a4", 4], ["a3", 3],["a2", 2], ["a1", 1]]
a_pick = random.randint(0,3)
a_score = (a_list[a_pick])

这种方法让我能够从列表中随机选择,同时保持我已经编写的配对。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接