-1

所以这可能是一个愚蠢的问题,但我很难说,所以很难用谷歌搜索。python的引用是如何工作的?最具体地说,我一直在研究神经网络中的反向传播,当我制作一个简单的测试网络时,我遇到了一个问题。这是开始的代码:

out = self.nodes[-1]
for i in range(len(self.nodes)):
 for j in range(len(self.nodes[i])):
  self.nodes[i][j]=0.0
return out

如果我这样运行它,它每次都会返回 0.0,但如果我注释掉重置它会准确地输出一个数字。我怎样才能出去引用值而不是变量?

4

2 回答 2

2

如果您想out保留最后一个列表/元组的值nodes而不将它们重置为0.0您需要创建该对象的副本(nodes[-1])或手动将它们复制到新的列表/元组对象中,如果我理解正确的话,并且那是你的目标。您当前只是创建对 nodes[-1] 的引用,然后再遍历二维数组并将所有值重置为0.0,这意味着out仍将引用您重置为0.0值的内存中的所指对象。

out = nodes[-1].copy()  # This is the list/tuple with the (non-reset) values that you want to return
...  # iterate through the array here and reset
return out

这将返回最后一个元素的副本(即对内存中新的唯一nodes引用对象的新引用),以及创建副本时(在重置迭代之前)所处的状态。

不确定我是否理解正确,但忘记了列表和元组Python 中的对象并且行为如此是一个容易犯的错误。

这意味着: l0 = [0, 1] l1 = l0 l2 = l0.copy() l0.append(2)

print(l0)  # prints [0, 1, 2]
print(l1)  # prints [0, 1, 2]
print(l2)  # prints [0, 1]

l0并且l1是对内存中同一对象/所指对象的两个引用。通过copy()操作l2成为对内存中唯一且不相同的所指对象的引用。

另外:请注意 list.copy() 正如评论中所指出的那样,仅在 Python 3 中可用,并返回浅拷贝。使用copy.copy()/copy.deepcopy()分别创建浅/深拷贝;该模块在Python 2Python 3中可用。或者,可以通过 生成列表的浅表list(list_to_copy)副本。

此处的文档:

于 2013-08-01T09:00:05.127 回答
1

您需要复制最后一行,而不仅仅是引用它:

out = self.nodes[-1][:]

列表是可变的;基本上是对其他 python 对象的引用的有序容器,可让您添加、删除和更改引用。通过更改列表中的所有值,您将重新绑定列表中的这些引用。

self.nodes[-1]只是对该引用列表的引用。您没有复制这些参考资料;您只是复制了对容器的引用。

可以再次替换矩阵:

height, width = len(self.nodes), len(self.nodes[0])
self.nodes = [[0.0 for _ in range(width)] for _ in range(height)]

现在您重新绑定nodes,并创建新的嵌套列表,因此self.nodes[-1]在此代码之前将引用的最后一行。

于 2013-08-01T09:00:08.527 回答