Sorting and Ranking
Sort by Column
Pick the minimum-score row from the remaining pool repeatedly until the pool
is empty, collecting names in order. With pandas, df.sort_values('score')
returns a new DataFrame with all rows in ascending order by that column.
By hand
Extract scores and names as parallel lists. Keep a remaining index pool.
Each iteration picks the index of the minimum remaining score, appends the
matching name to result, and removes that index from the pool.
naive.py
Replay: real traced execution (multi-file project)
# trace: ignore records
records = [
{'name': 'al', 'score': 80},
{'name': 'bo', 'score': 55},
{'name': 'cy', 'score': 90},
{'name': 'di', 'score': 70},
]
scores = [r['score'] for r in records]
names = [r['name'] for r in records]
remaining = list(range(len(records)))
result = []
for _ in range(len(records)):
best = min(remaining, key=lambda i: scores[i])
result.append(names[best])
remaining.remove(best)
print('RESULT:', result)
{'name': 'al', 'score': 80},
2records = [3 {'name': 'al', 'score': 80},4 {'name': 'bo', 'score': 55},{'name': 'bo', 'score': 55},
3{'name': 'al', 'score': 80},4{'name': 'bo', 'score': 55},5{'name': 'cy', 'score': 90},{'name': 'cy', 'score': 90},
4{'name': 'bo', 'score': 55},5{'name': 'cy', 'score': 90},6{'name': 'di', 'score': 70},{'name': 'di', 'score': 70},
5 {'name': 'cy', 'score': 90},6 {'name': 'di', 'score': 70},7]records = [
1# trace: ignore records2records = [3 {'name': 'al', 'score': 80},scores ← [80, 55, 90, 70]
7]8scores = [r['score'] for r in records]9names = [r['name'] for r in records]values this step[80, 55, 90, 70]scoresnames ← ['al', 'bo', 'cy', 'di']
8scores = [r['score'] for r in records]9names = [r['name'] for r in records]10remaining = list(range(len(records)))values this step['al', 'bo', 'cy', 'di']namesremaining ← [0, 1, 2, 3]
9names = [r['name'] for r in records]10remaining = list(range(len(records)))11result = []values this step[0, 1, 2, 3]remainingresult ← []
10remaining = list(range(len(records)))11result = []12for _ in range(len(records)):values this step[]result_ ← 0
11result = []12for _ in range(len(records)):13 best = min(remaining, key=lambda i: scores[i])values this step0_best ← 1
12for _ in range(len(records)):13 best = min(remaining, key=lambda i: scores[i])14 result.append(names[best])values this step1bestresult ← ['bo']
13best = min(remaining, key=lambda i: scores[i])14result.append(names[best])15remaining.remove(best)values this step[] → ['bo']resultremaining ← [0, 2, 3]
14 result.append(names[best])15 remaining.remove(best)16print('RESULT:', result)values this step[0, 1, 2, 3] → [0, 2, 3]remaining_ ← 1
11result = []12for _ in range(len(records)):13 best = min(remaining, key=lambda i: scores[i])values this step0 → 1_best ← 3
12for _ in range(len(records)):13 best = min(remaining, key=lambda i: scores[i])14 result.append(names[best])values this step1 → 3bestresult ← ['bo', 'di']
13best = min(remaining, key=lambda i: scores[i])14result.append(names[best])15remaining.remove(best)values this step['bo'] → ['bo', 'di']resultremaining ← [0, 2]
14 result.append(names[best])15 remaining.remove(best)16print('RESULT:', result)values this step[0, 2, 3] → [0, 2]remaining_ ← 2
11result = []12for _ in range(len(records)):13 best = min(remaining, key=lambda i: scores[i])values this step1 → 2_best ← 0
12for _ in range(len(records)):13 best = min(remaining, key=lambda i: scores[i])14 result.append(names[best])values this step3 → 0bestresult ← ['bo', 'di', 'al']
13best = min(remaining, key=lambda i: scores[i])14result.append(names[best])15remaining.remove(best)values this step['bo', 'di'] → ['bo', 'di', 'al']resultremaining ← [2]
14 result.append(names[best])15 remaining.remove(best)16print('RESULT:', result)values this step[0, 2] → [2]remaining_ ← 3
11result = []12for _ in range(len(records)):13 best = min(remaining, key=lambda i: scores[i])values this step2 → 3_best ← 2
12for _ in range(len(records)):13 best = min(remaining, key=lambda i: scores[i])14 result.append(names[best])values this step0 → 2bestresult ← ['bo', 'di', 'al', 'cy']
13best = min(remaining, key=lambda i: scores[i])14result.append(names[best])15remaining.remove(best)values this step['bo', 'di', 'al'] → ['bo', 'di', 'al', 'cy']resultremaining ← []
14 result.append(names[best])15 remaining.remove(best)16print('RESULT:', result)values this step[2] → []remainingfor _ in range(len(records)):
11result = []12for _ in range(len(records)):13 best = min(remaining, key=lambda i: scores[i])stdout ← RESULT: ['bo', 'di', 'al', 'cy']
15 remaining.remove(best)16print('RESULT:', result)values this stepRESULT: ['bo', 'di', 'al', 'cy']stdout
With pandas
df.sort_values('score') returns a new sorted DataFrame — the original df
is unchanged. The snapshot shows names, scores, and the preserved (non-reset)
original index.
library.py
import pandas as pd
from dalib.display import set_display
set_display()
records = [
{'name': 'al', 'score': 80},
{'name': 'bo', 'score': 55},
{'name': 'cy', 'score': 90},
{'name': 'di', 'score': 70},
]
df = pd.DataFrame(records)
sorted_df = df.sort_values('score')
print('names:', sorted_df['name'].tolist())
print('scores:', sorted_df['score'].tolist())
print('index:', sorted_df.index.tolist())
print('RESULT:', sorted_df['name'].tolist())
names: ['bo', 'di', 'al', 'cy']
scores: [55, 70, 80, 90]
index: [1, 3, 0, 2]
RESULT: ['bo', 'di', 'al', 'cy']
Implementation notes
sort_valuesreturns a new DataFrame; the original is unchanged. Useinplace=Trueto sort in place, but prefer the default for readable pipelines.- The sorted result keeps the original row index (
[1, 3, 0, 2]above). Add.reset_index(drop=True)to renumber from 0. - Default order is ascending. Pass
ascending=Falsefor descending:df.sort_values('score', ascending=False). - Cross-reference:
sort-by-key(python-data-basics) for the pure-Python version;sort-array(python-numpy ch08) for the NumPy array version.