Python中的random.shuffle()在while循环中的应用

3

我有一个列表:

    k = [1,2,3,4,5]

现在我想把这个列表的三个排列方式列在另一个列表中,但是当我这样做时:
    x = []
    i = 0
    while i < 3:
        random.shuffle(k)
        x.append(k)
        i += 1

我得到了三个相同的排列k在x中,如下所示:
    x = [[1,3,5,2,4], [1,3,5,2,4], [1,3,5,2,4]]

与我期望的不同,应该是这样的: ```html

与我期望的不同,应该是这样的:

```
    x = [[1,5,4,2,3], [1,3,5,2,4], [5,3,4,1,2]]

请注意,由于k中的数据收集方式,无法将k放在循环内部,据我所知,这样做可以解决问题。真正的代码如下:
    def create_random_chromosomes(genes):
        temp_chromosomes = []
        chromosomes = []
        i = 0
        while i < 2000:
            print(genes)
            random.shuffle(genes)
            temp_chromosomes.append(genes)
            i += 1
        print(temp_chromosomes)
        for element in temp_chromosomes:
            if element not in chromosomes:
                chromosomes.append(element)
        return chromosomes
1个回答

8

打乱列表会就地改变它,而你正在创建对同一列表的3个引用。在打乱之前创建该列表的一个副本

x = []
for i in range(3):
    kcopy = k[:]
    random.shuffle(kcopy)
    x.append(kcopy)

我还简化了您的循环; 只需使用for i in range(3)。或者,将其放置在完整方法的上下文中:

def create_random_chromosomes(genes):
    temp_chromosomes = []
    chromosomes = []
    for i in range(2000):
        print(genes)
        randomgenes = genes[:]
        random.shuffle(randomgenes)
        temp_chromosomes.append(randomgenes)
    print(temp_chromosomes)
    for element in temp_chromosomes:
        if element not in chromosomes:
            chromosomes.append(element)
    return chromosomes

您可以通过使用 set 来进一步简化上述内容,以消除重复项:

def create_random_chromosomes(genes):
    chromosomes = set()
    randomgenes = genes[:]
    for i in range(2000):
        random.shuffle(randomgenes)
        chromosomes.add(tuple(randomgenes))
    return list(chromosomes)

这里使用随机基因列表的元组副本以适应集合内容的可哈希限制。
你甚至可以确保返回2000个唯一的项目:
def create_random_chromosomes(genes):
    chromosomes = set()
    randomgenes = genes[:]
    while len(chromosomes) < 2000:
        random.shuffle(randomgenes)
        chromosomes.add(tuple(randomgenes))
    return list(chromosomes)

谢谢,这很好用。我之前已经尝试过同样的方法,但在复制时没有在 k 后面添加“[:]”,所以它没有起作用。那么,添加“[:]”到底有什么作用? - Daquicker
1
你还可以使用 list(k) 替代 k[:] - Ashwini Chaudhary
似乎更高效的方式是在循环外部创建一个列表的单个副本,然后保持(重新)洗牌该副本即可... - martineau
@martineau:在列表之外创建一个单独的副本,换句话说,仍然是完全相同的问题;您正在就地修改一个列表,并仅添加引用。 - Martijn Pieters
@martineau:啊,没错,tuple()调用使得将randomgenes的副本移出循环变成了一个好主意。 - Martijn Pieters
显示剩余7条评论

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