Comparison with numpy VS PEP8 E712 boolean arrays

PEP8 E712 requires that "a comparison with True should be if cond is True: or if cond: ".

But if I follow this PEP8 , I get different / wrong results. Why?

 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?" 
+6
source share
2 answers

This tip applies only to if tests that check the "truth" of a value. numpy is another beast.

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

Note that a is True always False , because a is an array, not a logical one, and is performs a simple equality test (for example, only True is True ; None is not True ).

+2
source

Numpy "True" does not match "True", like Python "True", and therefore is terminated with an error:

 >>> 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'> 

In addition, in particular, PEP 8 tells DONT to use 'is' or '==' for Booleans:

 Don't compare boolean values to True or False using ==: Yes: if greeting: No: if greeting == True: Worse: if greeting is True: 

An empty numpy array checks false as an empty Python list or an empty dict does:

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

Unlike Python, a numpy array of one false element does a false check:

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

But you cannot use this logic with a numpy array with more than one element:

 >>> 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() 

Thus, the "spirit" of PEP 8 with Numpy should probably only verify the truth of each element:

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

Or use any :

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

And remember, this is not what you expect:

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

Since np.where returns a non-empty tuple.

+6
source

All Articles