python - 如何在不影响python中的(引用)地址的情况下更改列表的内容?
问题描述
我正在将我的 C++ 代码移植到 Python。在 C++ 中,我经常使用引用来维护数据源和“指针”之间的一些连接。一开始,我以为 Python 没有指针的概念,但经过一番研究,我发现如果不应用 deepcopy,两个列表之间的赋值会保持对源列表的引用。在下面的代码中,我试图创建一些 numpy 数组的列表,并有一个外部变量“指向”该列表,因此对外部引用的任何修改都会相应地更改内部数据。
import numpy as np
import copy
class myList:
_data = None
def __init__(self):
self._data = [np.array([1,2,3,4,5]), np.array([7,8,2,3,1]), np.array([9,9,3,7,5])]
def getData(self, reference=False):
if reference:
return self._data
else:
return copy.deepcopy(self._data)
if __name__ == '__main__':
dt = myList()
ref = dt.getData(reference=True)
print(id(dt._data), ' ', id(ref))
ref[1][3] = (k+1) * 11
print(dt)
上面的代码显示dt._data
和ref
共享相同的地址,并且任何更改ref
都会反映dt._data
,反之亦然。但是如果我需要dt._data
使用其他一些数据源来重置
if __name__ == '__main__':
dt = myList()
ref = dt.getData(reference=True)
newSrc = [np.array([1, 1, 1, 1, 1]), np.array([2, 2, 2, 2, 2]), np.array([3, 3, 3, 3, 3])]
dt._data = copy.deepcopy(newSrc)
print(id(dt._data), ' ', id(ref)) # different address shown
的地址dt._data
将改变,而ref
将保持不变。经过反复试验,我发现逐行执行分配似乎可以解决问题
if __name__ == '__main__':
dt = myList()
ref = dt.getData(reference=True)
newSrc = [np.array([1, 1, 1, 1, 1]), np.array([2, 2, 2, 2, 2]), np.array([3, 3, 3, 3, 3])]
for i in len(newSrc):
dt._data[i] = copy.deepcopy(newSrc[i])
print(id(dt._data), ' ', id(ref)) # sameaddress shown
我不确定这是否是解决问题的正确方法,但至少如果 newSrc 和 dt._data 的维度相同,它不会引发任何问题。但是如果 newSrc 的行数比 dt._data 多或少,这会导致问题吗?如果是,是否像 C/C++ 一样只是更改“指针”的内容(如 *pointer = ...)但保持地址不变Python?
解决方案
如果我正确理解了您的问题,您的代码实际上可以按您的预期工作。修改 中的值后ref
,修改类内的数组。只需更改代码的最后一行,即可看到差异为print(dt._data)
.
在您的代码中,当 时reference=True
,对象ref
的地址与dt._data
. 不过,我强烈建议使用 alwaysdt._data
以避免将来出现问题。为什么?因为如果您dt._data
稍后在代码中进行初始化,ref
则将不再指向其内容。
当您设置 时reference=False
,ref
将包含该时间点数组内容的精确副本。从那时起,它们将在您的代码中表现为完全不同的变量。
推荐阅读
- c# - 检索包含子组的组的成员
- java - 打印出一组斐波那契数列
- shell - How do I create the Windows Equivalent of This Very Small Shell Script?
- python - 无法在 google-cloud-run 上运行 selenium chrome-driver
- node.js - 在 NodeJS 中运行 Conda 命令
- c++ - 如何在小对角线上方和下方打印数组元素?
- java - 如何删除保管箱文件?
- html - Custom Icon for Select Drop Down based on value reactjs
- regex - VSCode Snippets:将文件名从 my_file_name 格式化为 MyFileName
- javascript - How to access a nested object inside a function