为什么 python 不覆盖非零数组?
Why doesn't python overwite non-zero arrays?
for k in range(0, popSiz):
for i in range(0, mn1[0]):
for j in range(0,mn1[1]):
theta1[i][j] = random.gauss(0, 1)
for i in range(0, mn2[0]):
for j in range(0,mn2[1]):
theta2[i][j] = random.gauss(0, 1)
GameLogic.globalDict["theta1-" + str(k)] = theta1
GameLogic.globalDict["theta2-" + str(k)] = theta2
theta1 = [[0 for x in range(mn1[1])] for y in range(mn1[0])] # this
theta2 = [[0 for x in range(mn2[1])] for y in range(mn2[0])] # and this
print(GameLogic.globalDict["theta1-0"]==GameLogic.globalDict["theta1-1"])
如果我评论最后两行(它说 # this
# and this
),它会使所有 .globalDict["theta1-" + str(k)]
相同。因此,如果它被评论,它会打印 true,如果没有,它会打印 false。我想知道这是为什么?我不明白其中的逻辑。
theta1
和 theta2
列表是对象。您的初始循环 修改 这些对象。然后,您将对这些对象的引用存储在 globalDict
.
中
然而,您随后再次修改相同的对象,显然所有引用都将指向修改后的字典。为了避免这种情况,您必须为每次迭代创建 新对象 。这就是为什么添加这两行会使行为发生变化。
你的情况和比较简单的类似:
>>> a = []
>>> d = {}
>>> d['a'] = a
>>> a.append(1)
>>> a
[1]
>>> d['a'] # modified because d is actually storing a reference to that list.
[1]
>>> a = [] # now a is a completely different object
>>> a
[]
>>> d['a'] # old reference keep original a value alive.
[1]
另请注意,它与 "zeroing" 数组没有任何关系。您可以将最后两行替换为:
theta1 = [el.copy() for el in theta1] # or list(el) for el in ...
theta2 = [el.copy() for el in theta2] # or el[:] for el in ...
实现相同的结果,因为下一个循环将覆盖这些值。
(唯一的区别是这不会在最后一次迭代中将 theta1
和 theta2
归零...)
顺便说一下:您 可能 最好使用 numpy.random.normal
生成随机数数组:
>>> numpy.random.normal(size=(5,5))
array([[ 1.16883072, -1.12038842, -0.14351093, 1.20373197, 0.79088439],
[-0.80960599, -0.56876464, 1.12962452, 0.20582962, -1.36239647],
[-1.07225523, 0.56895514, -0.07132619, 1.36478187, 0.62836829],
[ 0.69711124, -0.81957984, -1.27820196, 0.04203822, 1.68618401],
[-0.54687767, 0.34994992, -0.91724856, 0.2631614 , 0.08691433]])
for k in range(0, popSiz):
for i in range(0, mn1[0]):
for j in range(0,mn1[1]):
theta1[i][j] = random.gauss(0, 1)
for i in range(0, mn2[0]):
for j in range(0,mn2[1]):
theta2[i][j] = random.gauss(0, 1)
GameLogic.globalDict["theta1-" + str(k)] = theta1
GameLogic.globalDict["theta2-" + str(k)] = theta2
theta1 = [[0 for x in range(mn1[1])] for y in range(mn1[0])] # this
theta2 = [[0 for x in range(mn2[1])] for y in range(mn2[0])] # and this
print(GameLogic.globalDict["theta1-0"]==GameLogic.globalDict["theta1-1"])
如果我评论最后两行(它说 # this
# and this
),它会使所有 .globalDict["theta1-" + str(k)]
相同。因此,如果它被评论,它会打印 true,如果没有,它会打印 false。我想知道这是为什么?我不明白其中的逻辑。
theta1
和 theta2
列表是对象。您的初始循环 修改 这些对象。然后,您将对这些对象的引用存储在 globalDict
.
然而,您随后再次修改相同的对象,显然所有引用都将指向修改后的字典。为了避免这种情况,您必须为每次迭代创建 新对象 。这就是为什么添加这两行会使行为发生变化。
你的情况和比较简单的类似:
>>> a = []
>>> d = {}
>>> d['a'] = a
>>> a.append(1)
>>> a
[1]
>>> d['a'] # modified because d is actually storing a reference to that list.
[1]
>>> a = [] # now a is a completely different object
>>> a
[]
>>> d['a'] # old reference keep original a value alive.
[1]
另请注意,它与 "zeroing" 数组没有任何关系。您可以将最后两行替换为:
theta1 = [el.copy() for el in theta1] # or list(el) for el in ...
theta2 = [el.copy() for el in theta2] # or el[:] for el in ...
实现相同的结果,因为下一个循环将覆盖这些值。
(唯一的区别是这不会在最后一次迭代中将 theta1
和 theta2
归零...)
顺便说一下:您 可能 最好使用 numpy.random.normal
生成随机数数组:
>>> numpy.random.normal(size=(5,5))
array([[ 1.16883072, -1.12038842, -0.14351093, 1.20373197, 0.79088439],
[-0.80960599, -0.56876464, 1.12962452, 0.20582962, -1.36239647],
[-1.07225523, 0.56895514, -0.07132619, 1.36478187, 0.62836829],
[ 0.69711124, -0.81957984, -1.27820196, 0.04203822, 1.68618401],
[-0.54687767, 0.34994992, -0.91724856, 0.2631614 , 0.08691433]])