060. List Methods
Mutating operations on ordered collections
060. List Methods
Aryan’s monitor has an alert queue — a list of processes that have exceeded the memory threshold. New alerts go to the end; the operator acknowledges them from the front (oldest first):
alert_queue = []
# New alert arrives — add to end
alert_queue.append({"name": "Chrome", "rss_mb": 1200, "pid": 4521})
# High-priority alert — push to front for immediate attention
alert_queue.insert(0, {"name": "kernel_task", "rss_mb": 3000, "pid": 0})
# Operator acknowledges — pop from front (oldest = highest priority)
ack = alert_queue.pop(0)
print(f"Acknowledged: {ack['name']}")
# Display current alerts sorted by severity
display = sorted(alert_queue, key=lambda a: a["rss_mb"], reverse=True)
# Note: sorted() returns a new list — alert_queue is unchangedThe trap: calling .sort() on the display list would sort alert_queue in-place (they’re the same object) and destroy the arrival-order queue. sorted() returns a new list — the original stays intact.
💡 Fun fact: Python’s sort() and sorted() use Timsort — an algorithm invented by Tim Peters in 2002 specifically for Python. Timsort is a hybrid of merge sort and insertion sort that exploits naturally ordered “runs” in real-world data. It’s so effective that Java adopted it for Arrays.sort() in Java 7, and Android’s Java runtime also uses it. The algorithm’s author, Tim Peters, also wrote “The Zen of Python.”
⚠️ Watch out: .sort() mutates the list in-place and returns None. A very common bug is writing sorted_list = my_list.sort() — this assigns None to sorted_list and sorts my_list as a side effect. If you want a sorted copy without touching the original, always use sorted_list = sorted(my_list).
🤔 Think about it: pop(0) removes the first element of a list in O(n) time because every remaining element must shift left. For Aryan’s alert queue where he frequently acknowledges alerts from the front, a list is actually the wrong data structure. What Python data structure provides O(1) pops from both ends — and when would you use it instead of a list?
Learning objectives
- Use append() and insert() to add items
- Use pop() and pop(0) to remove items from end/beginning
- Distinguish sorted() (new list) from .sort() (in-place)
Key concepts
- list methods
- append()
- pop()
- insert()
- sorted()
Try it
Concept detail
Key list methods and their behavior:
Adding: append(x) — add x to end; O(1); returns None (mutates) insert(i, x) — insert x at index i; O(n); returns None (mutates) extend(items) — add all items to end; returns None (mutates)
Removing: pop() — remove and return last element; O(1) pop(i) — remove and return element at index i; O(n) for i=0 remove(x) — remove first occurrence of x; raises ValueError if absent
Searching: index(x) — find first index of x; raises ValueError if absent count(x) — count occurrences of x
Sorting: lst.sort() — sorts IN-PLACE; returns None; modifies original sorted(lst) — returns NEW sorted list; original unchanged
Rule of thumb: methods that mutate return None. Functions that create return new values. sorted() is always safe for display — it never touches the source list.
Solution
def add_task(tasks, task):
tasks.append(task)
return tasks
def complete_task(tasks):
return tasks.pop(0)
def prioritize(tasks, task):
tasks.insert(0, task)
return tasks
def sort_tasks(tasks):
return sorted(tasks)Tests
def test_add_task():
tasks = ["a", "b"]
add_task(tasks, "c")
assert tasks[-1] == "c"
assert tasks[0] == "a" # original order preserved
def test_complete_task():
tasks = ["first", "second", "third"]
done = complete_task(tasks)
assert done == "first"
assert tasks == ["second", "third"]
def test_prioritize():
tasks = ["b", "c"]
prioritize(tasks, "a")
assert tasks[0] == "a"
assert tasks == ["a", "b", "c"]
def test_sort_tasks_correct_order():
original = ["banana", "apple", "cherry"]
result = sort_tasks(original)
assert result == ["apple", "banana", "cherry"]
def test_sort_tasks_no_mutation():
original = ["banana", "apple", "cherry"]
sort_tasks(original)
assert original == ["banana", "apple", "cherry"] # unchanged!