为了账号安全,请及时绑定邮箱和手机立即绑定

np.ndarray`中的奇怪行为“是”

np.ndarray`中的奇怪行为“是”

小怪兽爱吃肉 2021-10-26 17:07:47
“is”内置运算符对 中的元素显示奇怪的行为np.ndarray。尽管 rhs 和 lhs 的 id 相同,但“is”运算符返回 False(此行为特定于np.ndarray)。a = np.array([1.,])b = a.view()print(id(a[0] == id(b[0])))  # Trueprint(a[0] is b[0])  # False这种奇怪的行为甚至在没有视图副本的情况下也会发生。a = np.array([1.,])print(a[0] is a[0])  # False有谁知道这种奇怪行为的机制(可能还有证据或规范)?Post Script:请重新思考这两个例子。如果这是一个列表,则不会观察到这种现象。a = [0., 1., 2.,]b = []b.append(a[0])print(a[0] is b[0])  # Truea[0] 和 b[0] 指的是完全相同的对象。a = np.array([1.,])b = a.view()b[0] = 0.print(a[0])  # 0.0print(id(a[0]) == id(b[0]))  # True注意:这个问题可能是重复的,但我仍然有点困惑。a = np.array([1.,])b = a.view()x = a[0]y = b[0]print(id(a[0]))  # 139746064667728print(id(b[0]))  # 139746064667728print(id(a[0]) == id(b[0])) # Trueprint(id(a[0]) == id(x)) # Falseprint(id(x) == id(y))  # Falsea[0] 是一个时间对象吗?时态对象的 id 是否被重用?这不与规范相矛盾吗?( https://docs.python.org/3.7/reference/expressions.html#is )6.10.3. Identity comparisonsThe operators is and is not test for object identity: x is y is true if and only if x and y are the same object. Object identity is determined using the id() function. x is not y yields the inverse truth value.如果 id 被重新用于临时对象,为什么在这种情况下 id 是不同的?>>> id(100000000000000000 + 1) == id(100000000000000001)True>>> id(100000000000000000 + 1) == id(100000000000000000)False
查看完整描述

3 回答

?
梵蒂冈之花

TA贡献1900条经验 获得超5个赞

这仅仅是由于 is 和 == 工作方式的不同,is 运算符不会比较它们只是检查两个操作数是否引用同一个对象的值。


例如,如果你这样做:


print(a is a)

输出将是: True 有关更多信息,请查看此处


当 python 比较时,它会为操作数分配不同的位置,并且可以通过使用 id 函数的简单测试观察到相同的行为。


print(id(a[0]),a[0] is a[0],id(a[0]))

输出将是:


140296834593128 False 140296834593248

您另外提出的问题的答案是为什么列表不像 numpy 数组的行为方式只是基于它们的构造。Np.arrays 被设计成比普通的 Python 列表在处理能力和存储方面更高效。


因此,每次在 numpy 数组上加载或执行操作时,它都会加载并分配不同的 id,您可以从以下代码中观察到:


a = np.array([0., 1., 2.,])

b = []

b.append(a[0])

print(id(a[0]),a[0] is b[0],id(b[0]))

以下是在 jupyter-lab 中多次重新运行相同代码的输出:


140296834595096 False 140296834594496

140296834595120 False 140296834594496

140296834595120 False 140296834594496

140296834595216 False 140296834594496

140296834595288 False 140296834594496

注意到一些奇怪的事情吗?,每次重新运行时 numpy 数组的 id 不同,但列表对象的 id 保持不变。这解释了您问题中 numpy 数组的奇怪行为。


如果您想阅读有关此行为的更多信息,我会建议使用numpy docs


查看完整回答
反对 回复 2021-10-26
?
一只甜甜圈

TA贡献1836条经验 获得超5个赞

这由id() 与 `is` 运算符涵盖。比较“id”是否安全?相同的 `id` 是否意味着相同的对象?. 在这种特殊情况下:


a[0]并且b[0]每次都重新创建


In [7]: a[0] is a[0]

Out[7]: False

在 中id(a[0]) == id(b[0]),每个对象在取其后立即丢弃id,而b[0]刚好取用了id最近丢弃的a[0]。即使每次在您的 CPython 版本中针对此特定表达式都会发生这种情况(由于特定的评估顺序和堆组织),这也是一个实现细节,您不能依赖它。


查看完整回答
反对 回复 2021-10-26
  • 3 回答
  • 0 关注
  • 156 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信