为什么python不覆盖非零数组?

2024-10-03 19:28:48 发布

您现在位置:Python中文网/ 问答频道 /正文

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。我想知道这是为什么?我不明白它的逻辑


Tags: andinforrangerandomthisstrgauss
1条回答
网友
1楼 · 发布于 2024-10-03 19:28:48

theta1theta2列表是对象。初始循环修改这些对象。然后将对这些对象的引用存储在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]

还要注意,它与“归零”数组没有任何关系。您可以将最后两行替换为:

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 ...

为了获得相同的结果,因为下一个循环将覆盖这些值。 (唯一的区别是这不会在上一次迭代中将theta1theta2归零…)


顺便说一下:使用^{}生成随机数数组可能会更好:

>>> 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]])

相关问题 更多 >