Python
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax and Data Types
-
Section 3: Collections
-
39: Set Operations: Union, Intersection, Difference
-
Section 4: Control Flow
-
Section 5: Functions
-
Section 6: Turtle Graphics and Early Practice Projects
-
Section 7: Working with Files and I/O
-
Section 8: Regular Expressions
-
Section 9: Object-Oriented Python
-
Section 10: Error Handling
-
Section 11: Modules and Packages
-
Section 12: Iterators, Generators, and Functional Tools
-
Section 13: Decorators and Metaprogramming
-
Section 14: Concurrency and Parallelism
-
Section 15: Working with Dates, Times, and Numbers
-
Section 16: Standard Library Deep Dive I: Data Structures
-
Section 17: Standard Library Deep Dive II: System and Introspection
-
Section 18: Standard Library Deep Dive III: Security and Encoding
-
Section 19: Standard Library Deep Dive IV: Text and Data Utilities
-
Section 20: Networking and Web Basics
-
Section 21: Working with Databases
-
Section 22: Testing and Quality
-
Section 23: Advanced Typing
-
Section 24: Context Managers and Resource Handling
-
Section 25: Text, Unicode, and Binary Data
-
Section 26: More Functional and Iteration Tools
-
Section 27: Data Validation and Configuration
-
Section 28: Working with Images and Media
-
Section 29: Property-Based and Documentation Testing
-
Section 30: Packaging and Deployment
-
Section 31: Performance and Internals
-
Section 32: Design Patterns in Python
-
Section 33: GUI Programming
-
Section 34: Security Basics
-
Section 35: Data Structures and Algorithms
-
Section 36: Practical Projects
-
Section 37: Capstone Projects
-
Section 38: Interview and Algorithm Practice
-
Section 39: Writing Idiomatic Python
56: List Comprehensions
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].
There are no comments for now.