所以这可能是一个愚蠢的问题,但我很难说,所以谷歌真的很难。 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,但如果我注释掉重置,它将准确地输出一个数字。我怎样才能引用值而不是变量?
答案 0 :(得分:2)
如果您希望out
保留nodes
中最后一个列表/元组的值而不将它们重置为0.0
,则需要创建该对象的副本({{ 1}})或者手动将它们复制到新的列表/元组对象中,如果我理解正确的话,那就是你的目标。
您目前只是在通过二维数组进行交互并将所有值重置为nodes[-1]
之前创建对节点[-1]的引用,这意味着,0.0
仍会引用内存中的指示对象重置为out
值。
0.0
现在将返回{strong>副本(即对内存中新的唯一指示对象的新引用)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
的最后一个元素它是在您创建副本时(在重置迭代之前)。
不确定我是否理解正确但忘记了Python中的列表和元组是对象,并且这样做很容易犯错误。
这意味着: l0 = [0,1] l1 = l0 l2 = l0.copy() l0.append(2)
nodes
print(l0) # prints [0, 1, 2]
print(l1) # prints [0, 1, 2]
print(l2) # prints [0, 1]
和l0
是对内存中同一对象/引用对象的两个引用。通过l1
操作copy()
成为对内存中唯一且不相同指示对象的引用。
添加:请注意,list.copy()正如评论中所指出的那样,仅在Python 3中提供并返回浅表副本。使用l2
/ copy.copy()
分别创建浅/深副本;此模块在 Python 2 和 Python 3 中可用。
或者,可以通过copy.deepcopy()
生成列表的浅副本。
此处的文档:
答案 1 :(得分: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]
。