The Health Check: How a Simple Dictionary Filter Reveals Your Engineering Mindset
Q: Given a dictionary of services and their status, write Python code to print only the services that are "DOWN".
Why this matters: This is a test of fluency. The interviewer isn't checking if you can write a loop. They're checking if you can think in Python. Your answer reveals whether you write code that is merely correct, or code that is clear, concise, and idiomatic—the hallmarks of a professional.
Interview frequency: Very high. A staple "can you code?" question.
❌ The Death Trap
The trap isn't writing incorrect code, but writing clumsy code. The candidate writes a verbose loop that works but feels like it was translated from another language (like C or Java). It gets the job done, but it misses the soul of Python.
"The merely correct, but uninspired, answer:"
services = {'api': 'UP', 'database': 'DOWN', 'cache': 'UP'}
down_services = []
for key in services.keys():
if services[key] == 'DOWN':
down_services.append(key)
for service in down_services:
print(service)
This works, but it's not fluent. Iterating over `keys()` just to do a lookup inside the loop (`services[key]`) is inefficient and verbose. It shows a lack of familiarity with more direct ways to iterate and filter in Python.
🔄 The Reframe
What they're really asking: "Can you express your intent directly? Show me you can write code that declares *what* you want, not just the step-by-step instructions for *how* to get it."
This reveals your relationship with the language. Do you see it as a set of tools to be assembled, or as a medium for expressing ideas? The Pythonic way values clarity and conciseness, which leads to more readable and maintainable code.
🧠 The Mental Model
I separate this into two styles of thinking: **The Recipe vs. The Request.**
📖 The War Story
Situation: "I was reviewing a pull request for a new SRE dashboard. Part of the code was responsible for pulling a large JSON object of system metrics and generating different lists for different UI components: high-CPU pods, low-memory nodes, services with high error rates, etc."
Challenge: "The code was a 50-line monstrosity of nested `for` loops and `if` statements. Each filter had its own verbose loop, creating an empty list, appending to it, and so on. It was incredibly difficult to tell at a glance what the business logic for each filter was."
Stakes: "The code was fragile. Adding a new filter for 'DEGRADED' services meant carefully inserting another multi-line block into this tangled mess, with a high risk of introducing a bug. The cognitive overhead was huge. It was a failure of expression, not of logic."
✅ The Answer
"Of course. I would first show the straightforward, readable approach with a standard loop, and then demonstrate the more concise and Pythonic way using a comprehension. Both are correct, but one expresses the intent more directly."
The Input Data
service_statuses = {
'api-gateway': 'UP',
'user-database': 'DOWN',
'redis-cache': 'UP',
'payment-processor': 'DEGRADED',
'auth-service': 'DOWN'
}
Option 1: The Clear `for` Loop (The Recipe)
This approach is perfectly fine, especially for beginners. It's explicit and easy to follow.
print("--- Using a for loop ---")
for service, status in service_statuses.items():
if status == 'DOWN':
print(service)
This is a big improvement over the `keys()` version because `.items()` efficiently gives us both the key and value in each iteration without a second lookup.
Option 2: The Pythonic Comprehension (The Request)
This is the fluent, idiomatic way. It collapses the entire loop and condition into a single, highly readable expression.
print("\n--- Using a list comprehension ---")
down_services = [service for service, status in service_statuses.items() if status == 'DOWN']
for service in down_services:
print(service)
This code reads almost like an English sentence: "Create a list of `service` for each `service, status` pair, but only if the `status` is 'DOWN'." This is the declarative style that Python excels at.
🎯 The Memorable Hook
"Good code tells the machine how to do something. Great code tells another developer what you were thinking."
This connects the choice of a comprehension directly to the principle of clear communication with future readers of your code (including your future self). It shows you're optimizing for clarity, not just for the interpreter.
💭 Inevitable Follow-ups
Q: "How would you find all services that are NOT 'UP'?"
Be ready: "I'd just change the condition in the comprehension: `if status != 'UP'`. This would catch both 'DOWN' and 'DEGRADED' statuses, which is often what you want for an alerting system."
Q: "What if the dictionary was massive, with millions of services, and you only needed to process the down services one at a time without storing them all in a new list?"
Be ready: "For that, I'd use a generator expression. By changing the square brackets `[]` to parentheses `()`, Python creates a generator object instead of a list. It yields one result at a time, making it incredibly memory-efficient for large datasets. For example: `down_service_gen = (service for service, status in ...)`."
🔄 Adapt This Framework
If you're junior: The clear `for` loop using `.items()` is a great, solid answer. Presenting the comprehension as an alternative shows you're learning and thinking about Pythonic style.
If you're senior: You should lead with the list comprehension as the default, correct answer for this task. You should be able to explain *why* it's preferred (clarity, conciseness, performance) and proactively bring up generator expressions as the solution for memory-constrained scenarios.
