Build a combined boolean mask from two conditions (lower and upper bound) and use it to filter a list. The first loop produces the mask with and; the second loop applies it with if m. The replay shows combined growing one boolean at a time, then filtered collecting only the values that pass both conditions.

By hand

With NumPy

(a > lo) & (a < hi) applies both comparisons elementwise and combines them with bitwise AND. The result is a boolean array, passed directly to a[mask] for boolean indexing.

naive.py
values = [1, 5, 3, 8, 4, 9]
lo = 2
hi = 6
combined = []
for v in values:
    combined.append(v > lo and v < hi)
filtered = []
for v, m in zip(values, combined):
    if m:
        filtered.append(v)
print('RESULT:', (combined, filtered))
library.py
import numpy as np

values = [1, 5, 3, 8, 4, 9]
lo, hi = 2, 6
a = np.array(values)
mask = (a > lo) & (a < hi)
filtered = a[mask]
print('mask: shape:', mask.shape, 'dtype:', mask.dtype, 'values:', mask.tolist())
print('filtered: shape:', filtered.shape, 'dtype:', filtered.dtype, 'values:', filtered.tolist())
print('RESULT:', (mask.tolist(), filtered.tolist()))
mask: shape: (6,) dtype: bool values: [False, True, True, False, True, False]
filtered: shape: (3,) dtype: int64 values: [5, 3, 4]
RESULT: ([False, True, True, False, True, False], [5, 3, 4])

Implementation notes

  • Use & (bitwise AND) and | (bitwise OR) on NumPy boolean arrays, not Python's and/or. Python's and/or operate on the truthiness of the whole array (raising an error for ambiguous multi-element arrays).
  • Parentheses are required: (a > lo) & (a < hi). Without them, & binds tighter than > and <, so a > lo & a < hi is parsed as a > (lo & a) < hi — a comparison chain, not two masked conditions.
  • The combined mask (a > lo) & (a < hi) is equivalent to a[a > k] from filter-with-mask generalized to a range.
  • Shape, dtype, and values are shown explicitly here because ndarray.__repr__ output varies with NumPy version and print options.