S1Q3 · Remove Elements at Two Given Indices¶
⚡ Quick Reference
Function: remove_elements_at_two_indices(l: list, i1: int, i2: int) -> None
Core idea: always delete the larger index first - removing a smaller index shifts later elements and invalidates the larger index.
def remove_elements_at_two_indices(l: list, i1: int, i2: int):
first, second = (i1, i2) if i1 > i2 else (i2, i1)
del l[first]
del l[second]
Key rules:
- Modifies l in-place - returns None
- Delete the larger index first to avoid index shift
- del l[i] removes element at index i in-place
Problem Statement¶
Problem
Write a function remove_elements_at_two_indices(l, i1, i2) that removes the elements at indices i1 and i2 from l in-place. Returns None.
Example:
l=[1,2,3,4,5,6,7], i1=5, i2=1
[1, 3, 4, 5, 7]
The index-shift problem¶
If you delete i2=1 first:
7 instead of 6 - wrong element deleted.
If you delete i1=5 first (larger):
2 - correct.
Always delete larger index first
Deleting an element shifts all elements to its right one position left. If you delete the smaller index first, the larger index is now off by one. Deleting the larger index first avoids this entirely.
Solution approaches¶
def remove_elements_at_two_indices(l: list, i1: int, i2: int):
for i in sorted([i1, i2], reverse=True):
del l[i]
Sort both indices in descending order, delete in that order. Scales if ever extended to more than two indices.
def remove_elements_at_two_indices(l: list, i1: int, i2: int):
if i1 > i2:
del l[i1]
del l[i2]
else:
del l[i2]
del l[i1]
Explicit ordering - always delete the larger first.
def remove_elements_at_two_indices(l: list, i1: int, i2: int):
del l[max(i1, i2)]
del l[min(i1, i2)]
max and min pick the right order in one expression each. Clean and readable.
def remove_elements_at_two_indices(l: list, i1: int, i2: int):
to_remove = {i1, i2}
kept = [v for i, v in enumerate(l) if i not in to_remove]
l[:] = kept
Build the filtered list, then use slice assignment l[:] = kept to modify l in-place. The set lookup is O(1). Works correctly regardless of index order.
Key takeaways¶
Delete larger index first
Removing an element shifts all later indices left by 1. Always delete in descending index order to avoid invalidating the remaining index.
del vs pop()
del l[i] and l.pop(i) both remove by index in-place. del discards the value; pop(i) returns it. Use del when you don't need the removed value.
l[:] = new_list for in-place reassignment
l[:] = filtered replaces the contents of l in-place - the original list object is modified. l = filtered would just rebind the local variable and not affect the caller.