【问题标题】:Evaluating (False is False) is returning False in specific cases评估 (False is False) 在特定情况下返回 False
【发布时间】:2020-04-19 21:22:37
【问题描述】:

我在 Python 中遇到了一个奇怪的问题,其中评估涉及 np.linalg.norm 值的条件会导致问题。这是我的测试脚本:

import numpy as np

def isGoalReached():
    start = np.array([4, 5, 6])
    goal = np.array([17, 18, 19])
    dist = np.linalg.norm(start - goal)
    return (dist < 0.5)

print (isGoalReached())
print (isGoalReached() == 0)
print (isGoalReached() is False)

输出:

False
True
False

如果我删除 np.linalg.norm 部分,然后重写:

import numpy as np

def isGoalReached():
    dist = 123.456
    return (dist < 0.5)

print (isGoalReached())
print (isGoalReached() == 0)
print (isGoalReached() is False)

输出

False
True
True

是什么导致了这种非常奇怪的行为?我在 Python 3.7.3 (Anaconda)

【问题讨论】:

  • 确实很奇怪,但与您所说的相反,这不是问题,因为您根本不应该比较布尔值(通过is 或其他方式)。
  • 其中一个是 Python bool,另一个是 numpy.bool_。它们的类型不同。
  • 我只能看到Truth Value Testing文档中的正常行为。

标签: python numpy boolean


【解决方案1】:

似乎 np.linalg.norm 返回一个numpy.float64,当你进行比较时,类型是numpy.bool_

In [83]: np.bool_?                                                                                      
Init signature: np.bool_(self, /, *args, **kwargs)
Docstring:     
Boolean type (True or False), stored as a byte.

这就是is 不起作用的原因。如果你添加

return bool(dist < 0.5)

它会像你期望的那样工作。

【讨论】:

    【解决方案2】:

    您正在比较 id() 函数的返回值。

    它在文档中说:

    id(对象)

    返回对象的“身份”。这是一个整数 保证在此对象期间是唯一且恒定的 它的生命周期。两个生命周期不重叠的对象可能有 相同的 id() 值。

    CPython implementation detail: 这是对象的地址 记忆。

    即使您只有布尔值而不是某些 numpy 类型,也不能保证总是为它们获得相同的 id。

    使用== 比较布尔值,而不是is

    【讨论】:

    • “使用== 比较布尔值”——不,真的,请不要,至少不要与文字比较。写== True== False 是荒谬的。
    • @KonradRudolph if x == Trueif x == False 可以缩短为 if xif not x,但是如果你有两个布尔值 x 和 y 那么你应该写 x == y 而不是 x is y
    • 不是“可以”,应该是。这就是我的观点。至于比较两个布尔变量(例如x == y),我一方面可以数出我在二十多年的编程中必须这样做的次数。好的代码几乎不需要它。
    猜你喜欢
    • 2015-03-22
    • 1970-01-01
    • 2015-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多