Flag values that lie outside Tukey's 1.5×IQR fences. Compute Q1 and Q3 (the 25th and 75th percentiles), set fences at Q1 − 1.5×IQR and Q3 + 1.5×IQR, then mark any value strictly outside those fences as an outlier. By hand, sort the list and pick the quartile positions directly. With pandas, use Series.quantile() to get the same values in one call.

By hand

Sort the values, then compute Q1 and Q3 by picking the positions at (n−1)×0.25 and (n−1)×0.75 in the sorted array. With n=9 values, these positions are (8)×0.25 = 2 and (8)×0.75 = 6 — exact integers, so no interpolation is needed. The naive half picks sv[2] and sv[6] directly using int((n-1)*0.25), which matches pandas' default linear-interpolation quantile exactly for this data. Fences: lo = Q1 − 1.5×IQR, hi = Q3 + 1.5×IQR. Flag any value where v < lo or v > hi.

naive.py
values = [4, -10, 8, 50, 6, 12, 10, 16, 14]
sv = sorted(values)
n = len(sv)
q1 = sv[int((n - 1) * 0.25)]
q3 = sv[int((n - 1) * 0.75)]
iqr = q3 - q1
lo = q1 - 1.5 * iqr
hi = q3 + 1.5 * iqr
result = []
for v in values:
    result.append(v < lo or v > hi)
print('RESULT:', result)

With pandas

Series.quantile(p) uses linear interpolation by default. For this data the 25th and 75th percentile positions land on exact indices, so the result equals the naive pick. Build the fence flags with (df['x'] < lo) | (df['x'] > hi).

library.py
import pandas as pd
from dalib.display import set_display
set_display()

values = [4, -10, 8, 50, 6, 12, 10, 16, 14]
df = pd.DataFrame({'x': values})
q1 = df['x'].quantile(0.25)
q3 = df['x'].quantile(0.75)
iqr = q3 - q1
lo = q1 - 1.5 * iqr
hi = q3 + 1.5 * iqr
flags = (df['x'] < lo) | (df['x'] > hi)
result = flags.tolist()
print('q1:', q1, 'q3:', q3, 'iqr:', iqr)
print('lo:', lo, 'hi:', hi)
print('values:', df['x'].tolist())
print('RESULT:', result)
q1: 6.0 q3: 14.0 iqr: 8.0
lo: -6.0 hi: 26.0
values: [4, -10, 8, 50, 6, 12, 10, 16, 14]
RESULT: [False, True, False, True, False, False, False, False, False]

Implementation notes

  • The quartile method matters for parity: int((n-1)*p) gives the exact position only when (n-1)*p is an integer. Choosing n=9 makes both Q1 and Q3 positions integers, so naive and pandas agree without approximation.
  • Values exactly on a fence are not flagged — the condition is strict (< and >), consistent with Tukey's original definition.
  • The 1.5×IQR multiplier is Tukey's standard threshold; use 3×IQR for "extreme" outlier fences.
  • Cross-reference: stats-percentiles (statistics chapter) for a deeper look at percentile methods and interpolation.