Sorting and Ranking
Rank Assign
Assign 1-based ranks to a list of scores: the highest score gets rank 1, the
next gets rank 2, and so on. The sort step is treated as a known primitive;
the trace focuses on ranks and rank being updated one entry at a time.
By hand
sorted(range(len(names)), key=lambda i: scores[i], reverse=True) produces
order — the indices of names/scores from highest score to lowest.
Walking order with a counter rank fills ranks[names[i]] in the correct
sequence; rank increments after each assignment.
names = ['amy', 'bob', 'cal', 'dan', 'eve', 'fay']
scores = [72, 88, 55, 93, 61, 78]
order = sorted(range(len(names)), key=lambda i: scores[i], reverse=True)
ranks = {}
rank = 1
for i in order:
ranks[names[i]] = rank
rank = rank + 1
print('RESULT:', {k: ranks[k] for k in sorted(ranks)})
names ← ['amy', 'bob', 'cal', 'dan', 'eve', 'fay']
1names = ['amy', 'bob', 'cal', 'dan', 'eve', 'fay']2scores = [72, 88, 55, 93, 61, 78]values this step['amy', 'bob', 'cal', 'dan', 'eve', 'fay']namesscores ← [72, 88, 55, 93, 61, 78]
1names = ['amy', 'bob', 'cal', 'dan', 'eve', 'fay']2scores = [72, 88, 55, 93, 61, 78]3order = sorted(range(len(names)), key=lambda i: scores[i], reverse=True)values this step[72, 88, 55, 93, 61, 78]scoresorder ← [3, 1, 5, 0, 4, 2]
2scores = [72, 88, 55, 93, 61, 78]3order = sorted(range(len(names)), key=lambda i: scores[i], reverse=True)4ranks = {}values this step[3, 1, 5, 0, 4, 2]orderranks ← {}
3order = sorted(range(len(names)), key=lambda i: scores[i], reverse=True)4ranks = {}5rank = 1values this step{}ranksrank ← 1
4ranks = {}5rank = 16for i in order:values this step1ranki ← 3
5rank = 16for i in order:7 ranks[names[i]] = rankvalues this step3iranks ← {'dan': 1}
6for i in order:7 ranks[names[i]] = rank8 rank = rank + 1values this step{} → {'dan': 1}ranksrank ← 2
7 ranks[names[i]] = rank8 rank = rank + 19print('RESULT:', {k: ranks[k] for k in sorted(ranks)})values this step1 → 2ranki ← 1
5rank = 16for i in order:7 ranks[names[i]] = rankvalues this step3 → 1iranks ← {'dan': 1, 'bob': 2}
6for i in order:7 ranks[names[i]] = rank8 rank = rank + 1values this step{'dan': 1} → {'dan': 1, 'bob': 2}ranksrank ← 3
7 ranks[names[i]] = rank8 rank = rank + 19print('RESULT:', {k: ranks[k] for k in sorted(ranks)})values this step2 → 3ranki ← 5
5rank = 16for i in order:7 ranks[names[i]] = rankvalues this step1 → 5iranks ← {'dan': 1, 'bob': 2, 'fay': 3}
6for i in order:7 ranks[names[i]] = rank8 rank = rank + 1values this step{'dan': 1, 'bob': 2} → {'dan': 1, 'bob': 2, 'fay': 3}ranksrank ← 4
7 ranks[names[i]] = rank8 rank = rank + 19print('RESULT:', {k: ranks[k] for k in sorted(ranks)})values this step3 → 4ranki ← 0
5rank = 16for i in order:7 ranks[names[i]] = rankvalues this step5 → 0iranks ← {'dan': 1, 'bob': 2, 'fay': 3, 'amy': 4}
6for i in order:7 ranks[names[i]] = rank8 rank = rank + 1values this step{'dan': 1, 'bob': 2, 'fay': 3} → {'dan': 1, 'bob': 2, 'fay': 3, 'amy': 4}ranksrank ← 5
7 ranks[names[i]] = rank8 rank = rank + 19print('RESULT:', {k: ranks[k] for k in sorted(ranks)})values this step4 → 5ranki ← 4
5rank = 16for i in order:7 ranks[names[i]] = rankvalues this step0 → 4iranks ← {'dan': 1, 'bob': 2, 'fay': 3, 'amy': 4, 'eve': 5}
6for i in order:7 ranks[names[i]] = rank8 rank = rank + 1values this step{'dan': 1, 'bob': 2, 'fay': 3, 'amy': 4} → {'dan': 1, 'bob': 2, 'fay': 3, 'amy': 4, 'eve': 5}ranksrank ← 6
7 ranks[names[i]] = rank8 rank = rank + 19print('RESULT:', {k: ranks[k] for k in sorted(ranks)})values this step5 → 6ranki ← 2
5rank = 16for i in order:7 ranks[names[i]] = rankvalues this step4 → 2iranks ← {'dan': 1, 'bob': 2, 'fay': 3, 'amy': 4, 'eve': 5, 'cal': 6}
6for i in order:7 ranks[names[i]] = rank8 rank = rank + 1values this step{'dan': 1, 'bob': 2, 'fay': 3, 'amy': 4, 'eve': 5} → {'dan': 1, 'bob': 2, 'fay': 3, 'amy': 4, 'eve': 5, 'cal': 6}ranksrank ← 7
7 ranks[names[i]] = rank8 rank = rank + 19print('RESULT:', {k: ranks[k] for k in sorted(ranks)})values this step6 → 7rankfor i in order:
5rank = 16for i in order:7 ranks[names[i]] = rankstdout ← RESULT: {'amy': 4, 'bob': 2, 'cal': 6, 'dan': 1, 'eve': 5, 'fay': 3}
8 rank = rank + 19print('RESULT:', {k: ranks[k] for k in sorted(ranks)})values this stepRESULT: {'amy': 4, 'bob': 2, 'cal': 6, 'dan': 1, 'eve': 5, 'fay': 3}stdout
The Pythonic way
zip(scores, names) pairs each score with its name; sorted(..., reverse=True) orders by score descending; enumerate supplies the
0-based position, giving i + 1 as the 1-based rank. A final
{k: ranks[k] for k in sorted(ranks)} returns the dict sorted by name.
names = ['amy', 'bob', 'cal', 'dan', 'eve', 'fay']
scores = [72, 88, 55, 93, 61, 78]
ranks = {name: i + 1 for i, (s, name) in enumerate(sorted(zip(scores, names), reverse=True))}
result = {k: ranks[k] for k in sorted(ranks)}
print('RESULT:', result)
RESULT: {'amy': 4, 'bob': 2, 'cal': 6, 'dan': 1, 'eve': 5, 'fay': 3}
Implementation notes
ranksgrows visibly in the trace:{}→{'dan': 1}→{'dan': 1, 'bob': 2}→ … → the full 6-entry dict (60 chars, within the 80-char limit).- Ties are out of scope: with distinct scores, every rank is unique. Handling
ties requires dense/standard/min-rank strategies (see
scipy.stats.rankdata). {k: ranks[k] for k in sorted(ranks)}sorts the output dict by name for a deterministic, readable RESULT line.