我正在尝试在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)
答案 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)
行只会被更改一次。