Python bool与numpy bool_的行为差异及相关技术咨询
bool_ vs Python bool: Key Differences & Validation Tips Great catch on the quirky behavior between numpy's bool_ and Python's native bool! Let's tackle your questions one by one.
1. General Behavior Differences Beyond Numpy-Specific Methods
While numpy.bool_ is built to be compatible with Python's bool, there are several subtle but impactful differences in their everyday behavior:
- Identity checks (
is) fail: Python’sTrueandFalseare singletons—there’s only one instance of each in the runtime. Numpy creates newbool_instances every time you initialize one, sonp.bool_(True) is Truewill always returnFalse, even though their values are equivalent. - Type distinctions:
type(np.bool_(True))returns<class 'numpy.bool_'>, whiletype(True)returns<class 'bool'>. That said,isinstance(np.bool_(True), bool)will still returnTruebecause numpy’s scalar types are registered as subclasses of their Python counterparts for compatibility. - Negation behavior differs: Python’s
boolusesnotfor logical negation, and~performs bitwise negation (e.g.,~Truereturns-2sinceTruemaps to integer1). Fornumpy.bool_,~np.bool_(True)correctly returnsFalse—numpy overrides the bitwise operator to act as logical negation for boolean scalars. - Operation type persistence: Arithmetic operations on
numpy.bool_keep the result as a numpy numeric type. For example:np.bool_(True) + 1 # Returns 2 as numpy.int64 True + 1 # Returns 2 as native int - Hashing & serialization differences: The hash value of a
numpy.bool_instance doesn’t match its Pythonboolequivalent, which can cause issues if you use them as dictionary keys alongside native booleans. Tools likepicklealso treat them as distinct types during serialization.
2. How to Check if a Numpy Array Contains Only numpy.bool_
The simplest and most efficient method is to verify the array’s dtype:
import numpy as np # Numpy bool_ array arr_bool = np.array([1, 0, 2, 0], dtype=bool) print(arr_bool.dtype == np.bool_) # Returns True # Object array with Python bools arr_obj_bool = np.array([True, False, True, False], dtype=object) print(arr_obj_bool.dtype == np.bool_) # Returns False
If you need to handle edge cases where an object-dtype array might mix numpy.bool_ and Python bool (a rare scenario), you can validate each element (note: this is slower for large arrays):
def is_all_numpy_bool(arr): return all(isinstance(elem, np.bool_) for elem in arr.flat) # Test mixed array mixed_arr = np.array([np.bool_(True), False, np.bool_(False)], dtype=object) print(is_all_numpy_bool(mixed_arr)) # Returns False
For a more robust dtype check (in case of alias types), use np.issubdtype:
print(np.issubdtype(arr_bool.dtype, np.bool_)) # Returns True
Quick Reminder
As you noted, using is to compare boolean values is bad practice overall. Always prefer direct boolean checks like if greeting: instead of if greeting == True: or if greeting is True—this works seamlessly for both Python bool and numpy.bool_.
内容的提问来源于stack exchange,提问作者vurmux

