dra*_*ock 13 python boolean numpy pep8
我if今天在python 条款中遇到了意外的结果:
import numpy
if numpy.allclose(6.0, 6.1, rtol=0, atol=0.5):
print 'close enough' # works as expected (prints message)
if numpy.allclose(6.0, 6.1, rtol=0, atol=0.5) is True:
print 'close enough' # does NOT work as expected (prints nothing)
Run Code Online (Sandbox Code Playgroud)
经过一番探讨(即这个问题,特别是这个答案)之后,我明白了原因:type返回的numpy.allclose()是numpy.bool_而不是简单的旧bool,而且显然是foo = numpy.bool_(1),然后if foo将评估,True同时if foo is True将评估False.这似乎是is运营商的工作.
我的问题是:为什么numpy有自己的布尔类型,根据这种情况,最佳做法是什么?我可以写逃脱if foo:得到预期的行为在上面的例子,但我喜欢更严格if foo is True:,因为它排除之类的东西2,并[2]从返回True,有时显式类型检查是可取的.
aba*_*ert 17
你正在做一些被认为是反模式的事情.引用PEP 8:
不要使用==将布尔值与True或False进行比较.
Yes: if greeting:
No: if greeting == True:
Worse: if greeting is True:
Run Code Online (Sandbox Code Playgroud)
numpy不是为了促进你的非pythonic代码而设计的,这不是numpy中的错误.事实上,这是一个完美的例子,说明为什么你的个人习语是一种反模式.
正如PEP 8所说,使用is True甚至更糟糕== True.为什么?因为你正在检查对象标识:不仅结果必须在布尔上下文中(通常只需要你),并且等于布尔True值,它实际上必须是常量True.很难想象这是你想要的任何情况.
你特别不想在这里:
>>> np.True_ == True
True
>>> np.True_ is True
False
Run Code Online (Sandbox Code Playgroud)
所以,你所做的只是明确地使你的代码与numpy不兼容,以及各种其他C扩展库(可以想象一个纯Python库可以返回一个等于的自定义值True,但我不知道任何这样做) .
在您的特定情况下,没有理由排除2和[2].如果您阅读了文档numpy.allclose,那么显然不会返回它们.但是考虑一些其他功能,就像标准库中的许多功能一样,只是说它们评估为真或假.这意味着他们明确被允许返回其中一个真实的论点,并且经常会这样做.你为什么要考虑这个假?
最后,为什么numpy或任何其他C扩展库定义了这样的bool兼容但不是bool类型?
通常,这是因为它们包装了C int或C++ bool或其他类似的类型.在numpy的情况下,它包含一个值,该值可以存储在最快的机器字类型或单个字节(在某些情况下甚至可能是一个位),以适应性能,并且您的代码不必关心哪个,因为所有表示看起来都是一样的,包括真实和等于True常数.
为什么numpy有自己的布尔类型
空间和速度。Numpy将事物存储在紧凑的数组中;如果它可以将布尔值放入单个字节,则将尝试。使用Python对象不容易做到这一点,因为您必须存储引用,这会大大降低计算速度。
在上面的示例中,我可以放弃编写if foo:以获得预期的行为,但是如果foo为True,我更严格:因为它从返回True排除了2和[2]之类的东西,有时显式类型检查是理想的。
好吧,不要那样做。
| 归档时间: |
|
| 查看次数: |
3780 次 |
| 最近记录: |