Python:'inf is inf',但是“-inf 不是 -inf”?

Python: 'inf is inf', but '-inf is not -inf'?

Python 3.7

在编写最大值的搜索代码时,我遇到了负无穷大的奇怪行为。 有人可以解释为什么会这样吗?

>>> inf = float('inf')
>>> inf is inf
True
>>> (-inf) is (-inf)
False

而且我已经意识到使用 == 进行比较会更好,但我对上述问题的答案很感兴趣。

-inf 是一个产生新的 float 对象的操作,你在同一个表达式中使用它两次。产生了两个不同的对象,因为不需要 Python 实现来注意到两个子表达式可以 return 对同一对象的引用。

inf是一个变量,绑定到一个特定的对象。任何对象 is 本身,所以 inf is inf.

-inf 是一个表达式。它进行数学运算,并生成一个值为浮点负无穷大的对象。 Python 不保证这是否与具有该值的任何其他对象相同。在你的例子中,-inf 的两次评估恰好产生了不同的对象。

同样,没有承诺 -inf is -inf 会产生什么。当前的 CPython 实现恰好始终产生 False。 PyPy 的原语处理 produces True。不同的 Python 版本或实现可能会根据当前的内存压力不一致地生成 True 或 False,或者您是否 运行 这是作为脚本或交互,或任何其他因素。 CPython 本身已经存在对象标识在脚本或交互中不同的情况;例如,这个:

x = 1000
y = 1000
print(x is y)

在当前 CPython 实现中打印不同的东西,这取决于您是否 运行 它是交互式的。

我想补充一点:在Python中,当我们使用id()函数、is运算符、==运算符等时,真正的目标我们'重新使用的是 value,而不是 variable.

a is b 等于 id(a) == id(b).

在您的代码中,inf = float('inf') 将生成一个名为 inf 的值。

inf也是一个表达式,会被求值。

inf is inf 将是 True,因为两个表达式的计算值实际上是相同的。

在Python中,关注价值更好更容易。

例如,在CPython实现中:

a = 1
b = 1
a is b # will be true

a = 10000
b = 10000
a is b # will be false

a = '10000'
b = '10000'
a is b # will be true

如果我们关注变量,这样的事情很奇怪。如果我们关注值,如果我告诉你 CPython 实现有缓存池,它用于小 int 和一些文字 str 值,这样的事情又简单了:

由于缓存池的原因,small int 1被缓存了,str '10000'也被缓存了,big int 10000没有被缓存所以会创建两次。

尝试关注价值观。