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

“is”内置运算符对 中的元素显示奇怪的行为np.ndarray。


尽管 rhs 和 lhs 的 id 相同,但“is”运算符返回 False(此行为特定于np.ndarray)。


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

b = a.view()

print(id(a[0] == id(b[0])))  # True

print(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])  # True

a[0] 和 b[0] 指的是完全相同的对象。

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

b = a.view()

b[0] = 0.

print(a[0])  # 0.0

print(id(a[0]) == id(b[0]))  # True

注意:这个问题可能是重复的,但我仍然有点困惑。


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

b = a.view()

x = a[0]

y = b[0]

print(id(a[0]))  # 139746064667728

print(id(b[0]))  # 139746064667728

print(id(a[0]) == id(b[0])) # True

print(id(a[0]) == id(x)) # False

print(id(x) == id(y))  # False

a[0] 是一个时间对象吗?

时态对象的 id 是否被重用?

这不与规范相矛盾吗?( https://docs.python.org/3.7/reference/expressions.html#is )

6.10.3. Identity comparisons

The 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


小怪兽爱吃肉
浏览 158回答 3
3回答

梵蒂冈之花

这仅仅是由于 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 140296834594496140296834595120 False 140296834594496140296834595120 False 140296834594496140296834595216 False 140296834594496140296834595288 False 140296834594496注意到一些奇怪的事情吗?,每次重新运行时 numpy 数组的 id 不同,但列表对象的 id 保持不变。这解释了您问题中 numpy 数组的奇怪行为。如果您想阅读有关此行为的更多信息,我会建议使用numpy docs

一只甜甜圈

这由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 版本中针对此特定表达式都会发生这种情况(由于特定的评估顺序和堆组织),这也是一个实现细节,您不能依赖它。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python