Ch 6 — Data Structures
Ch 6 — Data Structures
Tracking a single process’s RAM is trivial. Tracking all 300 processes, their PIDs, their snapshots over time, and the unique set of process names currently running — that requires real data structures. This chapter gives Aryan the containers that will hold the heart of the RAM manager.
range
A lazy sequence of integers. Produces values on demand rather than building a whole list.
range(5) # 0, 1, 2, 3, 4
range(1, 11) # 1 … 10
range(0, 60, 5) # 0, 5, 10 … 55 (step 5)
range(10, 0, -1) # 10, 9, 8 … 1Lists
Ordered, mutable, allow duplicates. The most common container.
processes = ["chrome", "electron", "python", "java"]
# Indexing & slicing
processes[0] # 'chrome'
processes[-1] # 'java'
processes[1:3] # ['electron', 'python']
# Common list methods
processes.append("vscode") # add to end
processes.insert(1, "slack") # insert at index
processes.remove("java") # remove by value
processes.pop() # remove and return last
processes.pop(0) # remove and return at index
processes.sort() # sort in-place (alphabetical)
processes.reverse() # reverse in-place
len(processes) # count items
"chrome" in processes # TrueBuilding a snapshot list
ram_history = []
for _ in range(10):
ram_history.append(get_ram_pct())
# [72.1, 73.5, 74.0, 74.3, 73.9, ...]Tuples
Ordered, immutable, allow duplicates. Use for records that should not change.
snapshot = ("chrome", 4821, 1024.5, 73.5)
# name pid rss_mb pct
proc_name, pid, rss_mb, pct = snapshot # unpacking
# Named access by index
print(snapshot[0]) # 'chrome'Tuples are faster than lists and signal “this data is a fixed record.”
Sets
Unordered, no duplicates, mutable. Perfect for tracking unique process names.
seen_procs = {"chrome", "electron", "python"}
seen_procs.add("vscode")
seen_procs.discard("java") # safe remove — no error if absent
# Set operations
morning = {"chrome", "vscode", "python"}
evening = {"chrome", "slack", "python"}
morning & evening # {'chrome', 'python'} intersection
morning | evening # all unique names union
morning - evening # {'vscode'} difference
morning ^ evening # {'vscode', 'slack'} symmetric differenceDicts
Key-value pairs, ordered (Python 3.7+), mutable. The RAM manager’s core: {pid: snapshot_data}.
proc_map = {
4821: {"name": "chrome", "rss_mb": 1024.5, "pct": 73.5},
312: {"name": "kernel", "rss_mb": 128.0, "pct": 0.9},
9001: {"name": "electron", "rss_mb": 512.0, "pct": 36.7},
}
# Access
proc_map[4821]["name"] # 'chrome'
proc_map.get(9999, "unknown") # 'unknown' — safe default if key missing
# Iteration
for pid, info in proc_map.items():
print(f"PID {pid}: {info['name']} {info['rss_mb']:.1f} MB")
# Modification
proc_map[4821]["rss_mb"] = 1100.0
# Keys, values, items
list(proc_map.keys()) # [4821, 312, 9001]
list(proc_map.values()) # [{'name': 'chrome', ...}, ...]Nested Data
Combine lists, dicts, and tuples to model complex state.
history = {
"chrome": [1024, 1050, 1100, 1090], # RSS over time
"electron": [512, 520, 530],
}
# Access nested value
history["chrome"][-1] # 1090 — most recent snapshotloop-else
The else clause on a loop runs only when the loop was not terminated by break.
critical_pid = None
for pid, info in proc_map.items():
if info["pct"] > 90:
critical_pid = pid
break
else:
print("No critical processes found in this snapshot")Iteration Helpers
processes = ["chrome", "electron", "python"]
rss_list = [1024.5, 512.0, 64.0]
# enumerate — index + value
for i, name in enumerate(processes, start=1):
print(f"{i}. {name}")
# zip — pair two iterables
for name, rss in zip(processes, rss_list):
print(f"{name}: {rss} MB")Data Structure Comparison
flowchart LR
A[Data Structures] --> B[list]
A --> C[tuple]
A --> D[set]
A --> E[dict]
B --> F["Ordered, mutable, duplicates OK"]
C --> G["Ordered, immutable, duplicates OK"]
D --> H["Unordered, mutable, NO duplicates"]
E --> I["Key-value, ordered keys, mutable"]RAM Manager State Model
flowchart TD
A[proc_map dict] --> B["pid: int → keys"]
B --> C["name: str"]
B --> D["rss_mb: float"]
B --> E["pct: float"]
A --> F[seen_procs set]
F --> G["unique names — no duplicates"]
A --> H[ram_history list]
H --> I["snapshots over time — ordered"]
A --> J[snapshot tuple]
J --> K["fixed record — name, pid, rss, pct"]Key Takeaways
- Lists are ordered and mutable — use them for time-series RAM snapshots.
- Tuples are immutable records — use them for a single process snapshot that should not change.
- Sets automatically deduplicate — ideal for tracking which process names have been seen.
- Dicts map keys to values —
{pid: info_dict}is the natural shape of the RAM manager’s process table. enumerate()gives index + value;zip()pairs two iterables — both avoid manual index tracking.loop-elseruns only when a loop completes withoutbreak— useful for “not found” logic.- Nest lists, dicts, and tuples freely to model hierarchical system data.