【问题标题】:Creating n random lists创建 n 个随机列表
【发布时间】:2025-12-25 14:50:07
【问题描述】:

我想使用 python 创建 n 个随机的 10 个数字列表,并将这些列表放在一个变量中(ran)。

下面是我的代码:

from random import shuffle

def gen_random_list (num):
    ran = []
    k = [n for n in range(1, 11)]
    for i in range(num):
        shuffle(k)
        ran.append(k)
    return ran 

预期的输出应该是这样的:

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

但是,当我在 jupyter notebook 中运行它时,我得到了这个:

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

这只是最后一个随机列表的重复。我附上了下面输出的屏幕截图

screenshot in jupyter notebook

谁能告诉我问题出在哪里?

谢谢。

【问题讨论】:

    标签: python list random append jupyter-notebook


    【解决方案1】:

    Shuffle 正在将列表 l 改组到位。您在列表列表中有同一个列表的多个实例,因此它们都会同时被打乱。

    为了演示,在循环中添加print

    def init_par (pop_size):
        ''' generate the 1st generation of parents
        pop_size should be an positive integer number'''
        if not (isinstance(pop_size, int) and pop_size>1):
            raise TypeError('bad operand type')
        else:
            par = []
            l=list(range(1,11))
            for i in range(pop_size):
                print i,l, par
                shuffle(l)
                par.append(l)
        return par
    

    打印:

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

    由于par 中的每个条目都只是同一个列表的一个视图,所以当您随机播放一个条目时,似乎 会随机播放所有条目。

    要修复,每次循环创建一个新列表:

    def init_par (pop_size):
        ''' generate the 1st generation of parents
        pop_size should be an positive integer number'''
        if not (isinstance(pop_size, int) and pop_size>1):
            raise TypeError('bad operand type')
        else:
            par = []
            for i in range(pop_size):
                l=list(range(1,11)) # each one is a new list
                shuffle(l)
                par.append(l)
        return par
    

    更快的方法是使用sample vs shuffle,如下所示:

    def init_par (pop_size):
        ''' generate the 1st generation of parents
        pop_size should be an positive integer number'''
        if not (isinstance(pop_size, int) and pop_size>1):
            raise TypeError('bad operand type')
        else:
            l=range(1,11)
            return [sample(l, k=len(l)) for _ in range(pop_size)]
    

    【讨论】:

    • 你能告诉我为什么“追加”只追加最后一个随机列表三次吗?
    • 为了简单起见,您不应该将[n for n in range(1, 11)] 更改为list(range(1, 11))l[:] 更改为l.copy() 吗?或者这对初学者来说是一个糟糕的答案?
    • @MegaIng:很好的建议!已添加。
    • @Dyckia:因为l 与您编写函数的方式相同。如果您随机播放 1 个 l 实例,则将它们全部随机播放。
    • @dawg 明白了。非常感谢!