Sorting and Ranking
Sort by Key
Order a list of names by a paired numeric score using a repeated selection-of-minimum. Each step picks the index of the lowest remaining score, appends the corresponding name to the result, then removes that index so it cannot be chosen again.
By hand
remain starts as [0, 1, 2, 3, 4, 5] — the full set of available indices.
Each iteration calls min(remain, key=lambda i: scores[i]) to find which
remaining index has the lowest score, appends names[best] to result, then
removes best from remain. When remain is empty the loop exits.
naive.py
Replay: real traced execution (multi-file project)
names = ['eve', 'bob', 'dan', 'amy', 'cal', 'fay']
scores = [72, 45, 88, 31, 63, 57]
remain = list(range(len(names)))
result = []
while remain:
best = min(remain, key=lambda i: scores[i])
result.append(names[best])
remain.remove(best)
print('RESULT:', result)
names ← ['eve', 'bob', 'dan', 'amy', 'cal', 'fay']
1names = ['eve', 'bob', 'dan', 'amy', 'cal', 'fay']2scores = [72, 45, 88, 31, 63, 57]values this step['eve', 'bob', 'dan', 'amy', 'cal', 'fay']namesscores ← [72, 45, 88, 31, 63, 57]
1names = ['eve', 'bob', 'dan', 'amy', 'cal', 'fay']2scores = [72, 45, 88, 31, 63, 57]3remain = list(range(len(names)))values this step[72, 45, 88, 31, 63, 57]scoresremain ← [0, 1, 2, 3, 4, 5]
2scores = [72, 45, 88, 31, 63, 57]3remain = list(range(len(names)))4result = []values this step[0, 1, 2, 3, 4, 5]remainresult ← []
3remain = list(range(len(names)))4result = []5while remain:values this step[]resultwhile remain:
4result = []5while remain:6 best = min(remain, key=lambda i: scores[i])best ← 3
5while remain:6 best = min(remain, key=lambda i: scores[i])7 result.append(names[best])values this step3bestresult ← ['amy']
6best = min(remain, key=lambda i: scores[i])7result.append(names[best])8remain.remove(best)values this step[] → ['amy']resultremain ← [0, 1, 2, 4, 5]
7 result.append(names[best])8 remain.remove(best)9print('RESULT:', result)values this step[0, 1, 2, 3, 4, 5] → [0, 1, 2, 4, 5]remainwhile remain:
4result = []5while remain:6 best = min(remain, key=lambda i: scores[i])best ← 1
5while remain:6 best = min(remain, key=lambda i: scores[i])7 result.append(names[best])values this step3 → 1bestresult ← ['amy', 'bob']
6best = min(remain, key=lambda i: scores[i])7result.append(names[best])8remain.remove(best)values this step['amy'] → ['amy', 'bob']resultremain ← [0, 2, 4, 5]
7 result.append(names[best])8 remain.remove(best)9print('RESULT:', result)values this step[0, 1, 2, 4, 5] → [0, 2, 4, 5]remainwhile remain:
4result = []5while remain:6 best = min(remain, key=lambda i: scores[i])best ← 5
5while remain:6 best = min(remain, key=lambda i: scores[i])7 result.append(names[best])values this step1 → 5bestresult ← ['amy', 'bob', 'fay']
6best = min(remain, key=lambda i: scores[i])7result.append(names[best])8remain.remove(best)values this step['amy', 'bob'] → ['amy', 'bob', 'fay']resultremain ← [0, 2, 4]
7 result.append(names[best])8 remain.remove(best)9print('RESULT:', result)values this step[0, 2, 4, 5] → [0, 2, 4]remainwhile remain:
4result = []5while remain:6 best = min(remain, key=lambda i: scores[i])best ← 4
5while remain:6 best = min(remain, key=lambda i: scores[i])7 result.append(names[best])values this step5 → 4bestresult ← ['amy', 'bob', 'fay', 'cal']
6best = min(remain, key=lambda i: scores[i])7result.append(names[best])8remain.remove(best)values this step['amy', 'bob', 'fay'] → ['amy', 'bob', 'fay', 'cal']resultremain ← [0, 2]
7 result.append(names[best])8 remain.remove(best)9print('RESULT:', result)values this step[0, 2, 4] → [0, 2]remainwhile remain:
4result = []5while remain:6 best = min(remain, key=lambda i: scores[i])best ← 0
5while remain:6 best = min(remain, key=lambda i: scores[i])7 result.append(names[best])values this step4 → 0bestresult ← ['amy', 'bob', 'fay', 'cal', 'eve']
6best = min(remain, key=lambda i: scores[i])7result.append(names[best])8remain.remove(best)values this step['amy', 'bob', 'fay', 'cal'] → ['amy', 'bob', 'fay', 'cal', 'eve']resultremain ← [2]
7 result.append(names[best])8 remain.remove(best)9print('RESULT:', result)values this step[0, 2] → [2]remainwhile remain:
4result = []5while remain:6 best = min(remain, key=lambda i: scores[i])best ← 2
5while remain:6 best = min(remain, key=lambda i: scores[i])7 result.append(names[best])values this step0 → 2bestresult ← ['amy', 'bob', 'fay', 'cal', 'eve', 'dan']
6best = min(remain, key=lambda i: scores[i])7result.append(names[best])8remain.remove(best)values this step['amy', 'bob', 'fay', 'cal', 'eve'] → ['amy', 'bob', 'fay', 'cal', 'eve', 'dan']resultremain ← []
7 result.append(names[best])8 remain.remove(best)9print('RESULT:', result)values this step[2] → []remainwhile remain:
4result = []5while remain:6 best = min(remain, key=lambda i: scores[i])stdout ← RESULT: ['amy', 'bob', 'fay', 'cal', 'eve', 'dan']
8 remain.remove(best)9print('RESULT:', result)values this stepRESULT: ['amy', 'bob', 'fay', 'cal', 'eve', 'dan']stdout
The Pythonic way
zip(names, scores) pairs each name with its score; sorted(..., key=lambda x: x[1]) orders by the score field; the comprehension strips the score back
out, leaving the sorted names.
library.py
names = ['eve', 'bob', 'dan', 'amy', 'cal', 'fay']
scores = [72, 45, 88, 31, 63, 57]
result = [n for n, s in sorted(zip(names, scores), key=lambda x: x[1])]
print('RESULT:', result)
RESULT: ['amy', 'bob', 'fay', 'cal', 'eve', 'dan']
Implementation notes
- Data is stored in parallel lists because a list of record dicts would exceed
the 80-character repr limit after two elements;
tupleis also not in the tracer's tracked types, so index integers are used instead. remainshrinks by one per step andresultgrows by one — both are visible in the trace. Thewhile remain:condition events are zero-delta (condition evaluation changes no variables).- The selection-of-minimum approach makes O(n²) comparisons;
sorteduses Timsort at O(n log n). For six elements the difference is negligible.