【发布时间】:2020-11-19 14:02:57
【问题描述】:
考虑以下几点:
from scipy.spatial import ConvexHull
import numpy as np
pts = np.random.rand(30, 2)
hull = ConvexHull(pts)
foo = hull.points
foo[0] = 4
print(pts[0]) # -> [4. 4.]
bar = foo[0]
bar[0] = 8
print(pts[0]) # -> [8. 4.]
我怎么知道修改 hull.points(或 foo,对 hull.points 的引用)正在修改 pts?
文档只说:
points: ndarray of double, shape (npoints, ndim)
Coordinates of input points.
pycharm 中的检查器还告诉我 foo 和 hull.points 都是 ndarray 并且代码、文档中没有任何内容,检查器告诉我我的变量实际上是引用相同值的指针(是的,我来自C,对不起)
它可能会很快出错,因为如果我直接修改“pts”的单个元素(包含我的其他变量/指针引用的所有值的二维数组)它也会修改我的所有变量和我的凸包“条”不再是凸的:
...
pts[0] = 16
print(bar) # -> [16. 16.]
除非我再次打电话
pts = np.random.rand(30, 2)
print(bar) # -> [16. 16.]
print(pts[0]) # -> [some random value]
pts 显然在新的内存位置变成了一个完全不同的对象,因此在这种特定情况下,bar 不再是对 pts 的引用。
而且它可以永远持续下去:如果我现在修改 foo = hull.points 那么 bar 不再是对 foo 的引用(嗯......它是对“旧 foo”的引用,不再可以访问了)
我的用例:所有参数都传递并返回不同方法的值:我正在失去对所有参考和值的跟踪。我最终在不知不觉中返回了一个值列表,尽管我修改了(也在不知不觉中)一个引用(因此是原始的ndarray),我什至不知道我的返回值是一个引用还是一个独立的对象安全修改,不会弄乱其他所有内容。
完全简化的用例:
from scipy.spatial import ConvexHull
import numpy as np
pts = np.random.rand(30, 2)
hull = ConvexHull(pts)
foo = hull.points
foo[0] = 4
print(pts[0]) # -> [4. 4.]
bar = foo[0]
bar[0] = 8
print(pts[0]) # -> [8. 4.]
qux = bar[0] # WOOPS /!\ qux isn't a reference to an ndarray element, it's just a "float" value
bar[0] = 16 # BUT this is a reference so i end up modifying pts BUT not qux /!\
print(pts[0], foo[0], bar, qux) # -> [16. 4.] [16. 4.] [16. 4.] 8.0
qux = bar # /!\ qux is now again a reference to pts
qux[0] = 128
print(pts[0], foo[0], bar, qux) # -> [128. 4.] [128. 4.] [128. 4.] [128. 4.]
qux = foo[0] # remember that qux = bar[0] didn't create a reference ?
qux[0] = 256 # but in this case, it is ! bar[0] is just a single float value while foo[0] is a reference to a ndarray
print(pts[0], foo[0], bar, qux) # -> [256. 4.] [256. 4.] [256. 4.] [256. 4.]
因为这非常“有趣”。现在我有 qux 和 bar 引用 foo[0],如果我说 foo = None qux 和 bar 会发生什么?没什么... qux 一个栏仍然引用 pts[0] 即使我从未明确说过...我很迷茫。
我也想知道我是否不是特殊情况,因为它是 numpy/scipy/ndarray。我以前从来没有这样挣扎过。 (我很幸运?)
【问题讨论】:
标签: python scipy numpy-ndarray