AI Skill Report Card
Using Bisect Module
Quick Start14 / 15
Pythonfrom bisect import bisect_left, bisect_right, insort_left, insort_right sorted_list = [1, 3, 4, 4, 6, 8] # Find insertion point (no mutation) idx = bisect_right(sorted_list, 4) # 4 -> insert after existing 4s # Insert while keeping list sorted insort_right(sorted_list, 5) # sorted_list -> [1, 3, 4, 4, 5, 6, 8]
Recommendation▾
Add an edge case example for empty lists or single-element lists
Workflow13 / 15
- Decide left vs right semantics for duplicate handling:
bisect_left/insort_left: insertion point before existing equal entriesbisect_right/insort_right(akabisect/insort): insertion point after existing equal entries
- Use
bisect_*when you only need the index (e.g., for grading/lookup tables, avoiding a full insert). - Use
insort_*when you need to mutate the list to keep it sorted after adding a value. - For custom sort keys (Python 3.10+), pass
key=instead of pre-transforming the list:Pythonbisect_left(data, target, key=lambda x: x.value) - For narrowing search range, use
loandhiparameters to limit the search to a slice[lo, hi). - Never call these on an unsorted list — behavior is undefined/incorrect.
Recommendation▾
Mention time complexity trade-offs (O(log n) search vs O(n) insertion) more prominently early on
Examples18 / 20
Example 1: Grade lookup table Input:
Pythondef grade(score, breakpoints=[60, 70, 80, 90], grades='FDCBA'): from bisect import bisect i = bisect(breakpoints, score) return grades[i] [grade(s) for s in [55, 60, 61, 89, 90, 100]]
Output: ['F', 'D', 'D', 'C', 'A', 'A']
Example 2: Insert maintaining order with objects Input:
Pythonfrom bisect import insort_right from dataclasses import dataclass @dataclass class Event: time: int events = [Event(1), Event(5), Event(10)] insort_right(events, Event(7), key=lambda e: e.time) [e.time for e in events]
Output: [1, 5, 7, 10]
Example 3: Finding index without inserting Input:
Pythonfrom bisect import bisect_left data = [10, 20, 30, 40] bisect_left(data, 25)
Output: 2
Recommendation▾
Include a brief note on when NOT to use bisect (e.g., for unsorted data structures like heaps, or when a different data structure like a sorted container library would be better)
Best Practices
- Prefer
bisect_left/bisect_rightover writing manual binary search loops. - Use
key=parameter (3.10+) instead of maintaining a parallel list of keys. - For repeated insertions building a sorted list from scratch,
insortin a loop is O(n²) total — consider sorting once at the end if inserting many items at once. - Use
bisect_left(a, x)to check membership:i = bisect_left(a, x); found = i < len(a) and a[i] == x.
Common Pitfalls
- Calling
bisect/insortfunctions on unsorted data — results are meaningless. - Confusing
bisect_leftandbisect_rightwhen duplicates matter (affects where equal values land). - Using
insortrepeatedly in a hot loop for large datasets — O(n) shifting cost per insert dominates; batch and sort instead when possible. - Forgetting that
bisect/insortare aliases forbisect_right/insort_right, notbisect_left/insort_left.