Comparison with boolean numpy arrays VS PEP8 E712

前端 未结 2 1066
情书的邮戳
情书的邮戳 2020-12-20 18:10

PEP8 E712 requires that \"comparison to True should be if cond is True: or if cond:\".

But if I follow this

相关标签:
2条回答
  • 2020-12-20 18:29

    That advice only applies to if statements testing for the "truthiness" of a value. numpy is a different beast.

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

    Note that a is True is always False because a is an array, not a boolean, and is does a simple reference equality test (so only True is True; None is not True for example).

    0 讨论(0)
  • 2020-12-20 18:42

    Numpy's 'True' is not the same 'True' as Python's 'True' and therefor is fails:

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

    Also, specifically, PEP 8 says DONT 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 does test falsey just as an empty Python list or empty dict does:

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

    Unlike Python, a numpy array of a single falsey element does test falsey:

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

    But you cannot use that 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()
    

    So the 'spirit' of PEP 8 with Numpy is probably to only test each element's truthiness:

    >>> 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 be aware that this is not what you expect:

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

    Since np.where is returning a nonempty tuple.

    0 讨论(0)
提交回复
热议问题