Partition n samples into k equal contiguous folds by index. For each fold f, the test indices are [f*fold_size, (f+1)*fold_size); the rest are train. Library: KFold(n_splits=k, shuffle=False) yields identical index splits. RESULT: list of test-index lists per fold.

By hand

n=6, k=3, fold_size=2. Fold 0: test=[0,1], train=[2,3,4,5]. Fold 1: test=[2,3], train=[0,1,4,5]. Fold 2: test=[4,5], train=[0,1,2,3].

naive.py
Replay: real traced execution (multi-file project)
n = 6
k = 3
fold_size = n // k
folds = []
for f in range(k):
    start = f * fold_size
    end = start + fold_size
    test_idx = list(range(start, end))
    folds.append(test_idx)
print('RESULT:', folds)
  1. n ← 6

    1n = 62k = 3
    values this step6n
  2. k ← 3

    1n = 62k = 33fold_size = n // k
    values this step3k
  3. fold_size ← 2

    2k = 33fold_size = n // k4folds = []
    values this step2fold_size
  4. folds ← []

    3fold_size = n // k4folds = []5for f in range(k):
    values this step[]folds
  5. f ← 0

    4folds = []5for f in range(k):6    start = f * fold_size
    values this step0f
  6. start ← 0

    5for f in range(k):6    start = f * fold_size7    end = start + fold_size
    values this step0start
  7. end ← 2

    6start = f * fold_size7end = start + fold_size8test_idx = list(range(start, end))
    values this step2end
  8. test_idx ← [0, 1]

    7end = start + fold_size8test_idx = list(range(start, end))9folds.append(test_idx)
    values this step[0, 1]test_idx
  9. folds ← [[0, 1]]

    8    test_idx = list(range(start, end))9    folds.append(test_idx)10print('RESULT:', folds)
    values this step[] [[0, 1]]folds
  10. f ← 1

    4folds = []5for f in range(k):6    start = f * fold_size
    values this step0 1f
  11. start ← 2

    5for f in range(k):6    start = f * fold_size7    end = start + fold_size
    values this step0 2start
  12. end ← 4

    6start = f * fold_size7end = start + fold_size8test_idx = list(range(start, end))
    values this step2 4end
  13. test_idx ← [2, 3]

    7end = start + fold_size8test_idx = list(range(start, end))9folds.append(test_idx)
    values this step[0, 1] [2, 3]test_idx
  14. folds ← [[0, 1], [2, 3]]

    8    test_idx = list(range(start, end))9    folds.append(test_idx)10print('RESULT:', folds)
    values this step[[0, 1]] [[0, 1], [2, 3]]folds
  15. f ← 2

    4folds = []5for f in range(k):6    start = f * fold_size
    values this step1 2f
  16. start ← 4

    5for f in range(k):6    start = f * fold_size7    end = start + fold_size
    values this step2 4start
  17. end ← 6

    6start = f * fold_size7end = start + fold_size8test_idx = list(range(start, end))
    values this step4 6end
  18. test_idx ← [4, 5]

    7end = start + fold_size8test_idx = list(range(start, end))9folds.append(test_idx)
    values this step[2, 3] [4, 5]test_idx
  19. folds ← [[0, 1], [2, 3], [4, 5]]

    8    test_idx = list(range(start, end))9    folds.append(test_idx)10print('RESULT:', folds)
    values this step[[0, 1], [2, 3]] [[0, 1], [2, 3], [4, 5]]folds
  20. for f in range(k):

    4folds = []5for f in range(k):6    start = f * fold_size
  21. stdout ← RESULT: [[0, 1], [2, 3], [4, 5]]

    9    folds.append(test_idx)10print('RESULT:', folds)
    values this stepRESULT: [[0, 1], [2, 3], [4, 5]]stdout

With scikit-learn

KFold(n_splits=3, shuffle=False).split(range(n)) yields (train_idx, test_idx) pairs per fold; shuffle=False keeps contiguous test segments, matching the manual boundary split exactly.

library.py
from sklearn.model_selection import KFold
from dalib.display import set_display
set_display()

n = 6
kf = KFold(n_splits=3, shuffle=False)
test_folds = []
train_folds = []
for train_idx, test_idx in kf.split(range(n)):
    train_folds.append(train_idx.tolist())
    test_folds.append(test_idx.tolist())
print('train_folds:', train_folds)
print('RESULT:', test_folds)
train_folds: [[2, 3, 4, 5], [0, 1, 4, 5], [0, 1, 2, 3]]
RESULT: [[0, 1], [2, 3], [4, 5]]

Implementation notes

  • fold_size = n // k assumes n divisible by k. For uneven n, KFold distributes the extra samples to the first folds — this manual version does not handle that case.
  • Each fold rotates through the dataset: the union of all test folds covers every sample index exactly once.
  • Cross-reference: train-test-split-fixed (ch01) for a single holdout split. Cross-validation uses k splits to average out the variance of any one split; cross-reference compare-two-model-scores (this chapter) for using fold scores to pick a model.