生成随机2D网格:Python每次多次追加同一行而不是新行

时间:2016-03-13 17:29:52

标签: python multidimensional-array

我正在尝试在Python中随机生成1和1的2D 20x20点阵。我正在生成20个不同的行,并且在我实际尝试将生成的行追加到大数组A之前,所有行似乎都很顺利。 print函数返回20个不同的随机生成的行,完全像我想要的那样,但是当我添加append函数时,它只将第一个生成的行追加到数组中20次。

这似乎很简单,但我感到困惑。你能解释一下为什么会这样,以及我如何解决它?这是我的代码:

from random import randint
# generating the lattice 
A = []
row = [0]*20
def genrow():
    for i in range(0,20):
        p = randint(1,100)
        if p < 50:
            row[i] = 1
        else:
            row[i] = -1
    return row

def newrow():                
    for j in range(0,20):
        genrow()
        print(row)
        A.append(row)

newrow()

print(A)

3 个答案:

答案 0 :(得分:2)

这是因为您使用全局row并且列表是可变的,因此您可以附加到该行的链接,但是您可以反复更改此行。

可能的解决方案是在追加之前复制行:

from random import randint
# generating the lattice 
A = []

def genrow():
    for i in range(0,20):
        p = randint(1,100)
        if p < 50:
            row[i] = 1
        else:
            row[i] = -1
    return row

def newrow():                
    for j in range(0,20):
        genrow()
        #print(row)
        A.append(row.copy()) # Copy it before appending.

newrow()

print(A)

另一种方法是在函数中创建新行并附加以下内容:

from random import randint
# generating the lattice 
A = []

def genrow():     
    row = [None] * 20 # Create a new row
    for i in range(0,20):
        row[i] = 1 if randint(1,100) < 50 else -1 # Notice I changed this to make it shorter
    return row

def newrow(): 
    for j in range(0,20):
        row = genrow() # Catch the returned row
        A.append(row) # Append the new row not as copy this time

newrow()
print(A)

你甚至可以通过列表推导使它更短:

from random import randint
# generating the lattice

def genrow():     
    return [1 if randint(1,100) < 50 else -1 for _ in range(20)]

def newrow(): 
    return [genrow() for _ in range(20)]

A = newrow()
print(A)

甚至可以将这些列表理解合并为一个:

def newrow(): 
    return [[1 if randint(1,100) < 50 else -1 for _ in range(20)] for _ in range(20)]

请注意,这些都是以不同的复杂性和方法做同样的事情。重要的事实是您要么copy要么创建您追加的新列表。所有其他的东西只是缩短(可能更快)。

答案 1 :(得分:0)

列表是一个可变对象,因此如果您有row_1 = row然后row_2 = row,那么,当您更改row_1时,row_2也会被修改。< / p>

你做了什么(假设缩进是我在评论中猜到的)

您有一个全局变量行,您可以在函数genrow()中修改 - 一直修改并覆盖旧结果。 请注意,您的函数没有输入,但甚至将此变量传递给您的函数也无济于事。因为它在函数内部和外部保留了一个具有许多不同名称的单个变量。

您需要在函数中生成一个新行。这就是全部!

为了进一步阅读,有趣的是,this link我今天得到了推荐,这是你需要理解的东西(好吧,如果你愿意;你需要只分配行在genrow())内。

或者,为简洁起见,这是您需要的所有代码:

import numpy as np
A = 2 * np.random.randint(0, 2, (20, 20)) - 1

所有......幻想破灭,不是吗? :)

答案 2 :(得分:0)

以下两段代码都应该在genrow函数定义中缩进。

row = [0]*20

if p < 50:
   row[i] = 1
else:
   row[i] = -1
return row

现在你执行20x的唯一代码是

for i in range(0,20):
        p = randint(1,100)

行只会被更改一次。