Skip to Content
Course content

56: List Comprehensions

Click on the "Edit" button in the top corner of the screen to edit your slide content.

I've been staring at this block of code for five minutes, and it just feels... excessive. I'm working with a list of raw product prices pulled from a messy CSV, and I need to clean them up and convert them into floats so I can actually do some math with them.

raw_prices = ["$12.50", "$45.00", "TBD", "$10.99", "N/A", "$5.00"]
clean_prices = []

for price in raw_prices:
    if price != "TBD" and price != "N/A":
        numeric_value = price.replace("$", "")
        clean_prices.append(float(numeric_value))

print(clean_prices)
# Output: [12.5, 45.0, 10.99, 5.0]

The Boilerplate Burden

Now, this works. It's readable. But if you're writing Python every day, you'll start to notice that this pattern—creating an empty list, looping through an iterable, checking a condition, and appending the result—happens constantly. It's a lot of scaffolding for a very simple goal: "Give me a new list based on this old one."

I want to see if I can collapse this. Python has this shorthand called list comprehensions that lets us move the logic inside the list brackets themselves. Let's try to rewrite the basic conversion first, ignoring the "TBD" errors for a second just to see the syntax.

# Trying the shorthand
clean_prices = [float(price.replace("$", "")) for price in raw_prices]
# Result: ValueError: could not convert string to float: 'TBD'

Yep, it crashed. Exactly as expected. But look at that line. [expression for item in iterable]. It's almost like reading a sentence: "Give me the float version of the price for every price in the raw list." It's much denser, but once your eyes adjust, it's actually faster to parse than a four-line loop.

Filtering Out the Noise

To fix that ValueError, I need my if statement back. In a list comprehension, the filter goes at the very end. I'll tell Python to only run the expression if the item meets a certain criteria.

raw_prices = ["$12.50", "$45.00", "TBD", "$10.99", "N/A", "$5.00"]

# Only process if it's not one of our "bad" strings
clean_prices = [float(p.replace("$", "")) for p in raw_prices if p not in ("TBD", "N/A")]

print(clean_prices) 
# Output: [12.5, 45.0, 10.99, 5.0]

That's the sweet spot. We've collapsed five lines of code into one without losing clarity. I personally prefer this because it separates the transformation (the float conversion) from the filtering (the if clause).

Handling Alternates

But wait—what if I don't want to just discard "TBD"? What if my boss tells me that any "TBD" or "N/A" should actually be treated as 0.0 so the accounting totals still work?

This is where people usually get tripped up. If you want an else, the logic has to move to the front of the comprehension. The filter at the end is for skipping items entirely; the logic at the front is for choosing what to put in the list.

# Using a ternary operator inside the comprehension
clean_prices = [float(p.replace("$", "")) if p not in ("TBD", "N/A") else 0.0 for p in raw_prices]

print(clean_prices)
# Output: [12.5, 45.0, 0.0, 10.99, 0.0, 5.0]

It's a bit more crowded now. If I find myself writing a comprehension this long, I usually stop and ask if it's still readable. If it's getting too complex, I'll go back to the standard for loop. The goal isn't to write the shortest code possible; it's to write the clearest code possible. But for simple filtering and mapping? List comprehensions are a superpower.




📋 Practical Task

Filtering and Formatting Server Log Codes

You have a list of raw server response codes as strings. Some are valid HTTP codes (like "200" or "404"), but others are corrupted entries (like "ERR" or "TIMEOUT").

Write a list comprehension that:

  • Filters out any entry that is not a digit (hint: use the .isdigit() method).
  • Converts the remaining valid codes from strings to integers.
  • Only keeps the codes that are 400 or higher (the error codes).

Starter Data:

log_codes = ["200", "404", "ERR", "500", "201", "TIMEOUT", "403", "200"]

Your final list should contain only the integers [404, 500, 403].

Rating
0 0

There are no comments for now.

to be the first to leave a comment.