与布尔numpy数组VS PEP8 E712的比较

时间:2013-03-01 18:49:15

标签: python numpy pep8

PEP8 E712要求“与True的比较应为if cond is True:if cond:”。

但如果我遵循这个PEP8,我会得到不同/错误的结果。为什么呢?

In [1]: from pylab import *

In [2]: a = array([True, True, False])

In [3]: where(a == True)
Out[3]: (array([0, 1]),)
# correct results with PEP violation

In [4]: where(a is True)
Out[4]: (array([], dtype=int64),)
# wrong results without PEP violation

In [5]: where(a)
Out[5]: (array([0, 1]),)
# correct results without PEP violation, but not as clear as the first two imho. "Where what?"

2 个答案:

答案 0 :(得分:9)

Numpy的'True'与Python'True'的'True'不同,因此is失败:

>>> import numpy as np
>>> a = np.array([True, True, False])
>>> a[:]
array([ True,  True, False], dtype=bool)
>>> a[0]
True
>>> a[0]==True
True
>>> a[0] is True
False
>>> type(a[0])
<type 'numpy.bool_'>
>>> type(True)
<type 'bool'>

另外,具体而言,PEP 8说DONT对布尔人使用'是'或'==':

Don't compare boolean values to True or False using ==:

Yes:   if greeting:
No:    if greeting == True:
Worse: if greeting is True:

一个空的numpy数组确实测试为false,就像空的Python列表或空字典一样:

>>> [bool(x) for x in [[],{},np.array([])]]
[False, False, False] 

与Python不同,单个falsey元素的numpy数组会测试falsey:

>>> [bool(x) for x in [[False],[0],{0:False},np.array([False]), np.array([0])]]
[True, True, True, False, False]

但是你不能在具有多个元素的numpy数组中使用该逻辑:

>>> bool(np.array([0,0]))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

所以PEP 8与Numpy的'精神'可能只是测试每个元素的真实性:

>>> np.where(np.array([0,0]))
(array([], dtype=int64),)
>>> np.where(np.array([0,1]))
(array([1]),)

或使用any

>>> np.array([0,0]).any()
False
>>> np.array([0,1]).any()
True

请注意,这不是您所期望的:

>>> bool(np.where(np.array([0,0])))
True

由于np.where返回非空元组。

答案 1 :(得分:3)

该建议仅适用于测试值的“真实性”的if语句。 numpy是一个不同的野兽。

>>> a = np.array([True, False]) 
>>> a == True
array([ True, False], dtype=bool)
>>> a is True
False

请注意,a is True始终为False,因为a是一个数组,而不是布尔值,而is执行简单的引用相等性测试(因此只有True is True }; None is not True例如)。