Four elements gathered from a 6-element list at non-contiguous positions [0, 2, 4, 5]. The trace shows p taking each index in turn and out growing with the selected value.

By hand

Walk the index list idx with a for loop. At each step, p holds the target position; append values[p] to out.

naive.py
Replay: real traced execution (multi-file project)
values = [10, 20, 30, 40, 50, 60]
idx = [0, 2, 4, 5]
out = []
for p in idx:
    out.append(values[p])
print('RESULT:', out)
  1. values ← [10, 20, 30, 40, 50, 60]

    1values = [10, 20, 30, 40, 50, 60]2idx = [0, 2, 4, 5]
    values this step[10, 20, 30, 40, 50, 60]values
  2. idx ← [0, 2, 4, 5]

    1values = [10, 20, 30, 40, 50, 60]2idx = [0, 2, 4, 5]3out = []
    values this step[0, 2, 4, 5]idx
  3. out ← []

    2idx = [0, 2, 4, 5]3out = []4for p in idx:
    values this step[]out
  4. p ← 0

    3out = []4for p in idx:5    out.append(values[p])
    values this step0p
  5. out ← [10]

    4for p in idx:5    out.append(values[p])6print('RESULT:', out)
    values this step[] [10]out
  6. p ← 2

    3out = []4for p in idx:5    out.append(values[p])
    values this step0 2p
  7. out ← [10, 30]

    4for p in idx:5    out.append(values[p])6print('RESULT:', out)
    values this step[10] [10, 30]out
  8. p ← 4

    3out = []4for p in idx:5    out.append(values[p])
    values this step2 4p
  9. out ← [10, 30, 50]

    4for p in idx:5    out.append(values[p])6print('RESULT:', out)
    values this step[10, 30] [10, 30, 50]out
  10. p ← 5

    3out = []4for p in idx:5    out.append(values[p])
    values this step4 5p
  11. out ← [10, 30, 50, 60]

    4for p in idx:5    out.append(values[p])6print('RESULT:', out)
    values this step[10, 30, 50] [10, 30, 50, 60]out
  12. for p in idx:

    3out = []4for p in idx:5    out.append(values[p])
  13. stdout ← RESULT: [10, 30, 50, 60]

    5    out.append(values[p])6print('RESULT:', out)
    values this stepRESULT: [10, 30, 50, 60]stdout

With NumPy

a[idx] accepts a list (or array) of integer positions and returns a new array of the gathered elements in one call — no explicit loop needed. The snapshot shows the result's shape, dtype, and values.

library.py
import numpy as np

values = [10, 20, 30, 40, 50, 60]
idx = [0, 2, 4, 5]
a = np.array(values)
out = a[idx]
print('shape:', out.shape)
print('dtype:', out.dtype)
print('values:', out.tolist())
print('RESULT:', out.tolist())
shape: (4,)
dtype: int64
values: [10, 30, 50, 60]
RESULT: [10, 30, 50, 60]

Implementation notes

  • Fancy indexing always returns a copy, not a view. Modifying the output array does not affect the original — unlike basic slicing, which returns a view.
  • The index list may contain duplicates or out-of-order positions: a[[2, 0, 2]] returns [30, 10, 30]. This flexibility is the key difference from slice syntax, which can only express contiguous or strided ranges.
  • Shape, dtype, and values are shown explicitly here because ndarray.__repr__ output varies with NumPy version and print options.