Welcome to the final post of Part 5! In this section, we moved beyond just writing code that works and began exploring the philosophy of writing code that is clean, efficient, and “Pythonic.”
To wrap up, we’ll first briefly recap the key Pythonic idioms and features we’ve learned. Then, for our project, we will do something new: we’ll take a piece of poorly written code and refactor it, step-by-step, into an elegant, Pythonic solution.
Part 5 Recap: The Pythonic Way
This part was all about style, elegance, and using Python’s best features. We started with the philosophy of Pythonic code and the Zen of Python (Post #113). We then saw this in action with:
- Idiomatic Syntax: Preferring direct
for
loops (Post #114), elegant f-strings (Post #115), the efficient.join()
method (Post #116), and clean chained comparisons (Post #117). - Powerful Unpacking: Using
*
and**
to handle variable-length assignments and to merge collections (Post #118, Post #119). - Comprehensions and Generators: Mastering the concise syntax of comprehensions (Post #120 Post #121 Post #122 Post #123 Post #124) and the memory-efficiency of generators (Post #125 Post #126 Post #127 Post #128).
- Functional Tools and Decorators: Exploring functional helpers like
map
andfilter
(Posts #130 Post #131 Post #132 Post #133 Post #134 Post #135) and the powerful decorator pattern for adding functionality to our functions (Posts #137 Post #138 Post #139 Post #140 Post #141).
Project: Refactoring a C-Style Script
Refactoring is the process of restructuring existing computer code—changing its internal structure—without changing its external behavior. It’s about improving the code’s design, readability, and maintainability.
Our Task: We have a script that takes a list of numbers. It needs to produce a new list of strings, where each string is formatted as “The square of X is Y”, but only for the positive, even numbers in the original list.
The “Before” Script
Here is a script that correctly solves the problem, but in a verbose, non-Pythonic, “C-style” way. It uses a manual while
loop, unnecessary nested if
s, and clumsy string concatenation.
numbers = [1, 2, 3, -4, 5, 6, -7, 8, 9, 10]
def process_list_unpythonic(data):
results = []
i = 0
while i < len(data):
num = data[i]
# Check conditions separately
if num > 0:
if num % 2 == 0:
# Manual string concatenation
square = num ** 2
line = "The square of " + str(num) + " is " + str(square)
results.append(line)
i = i + 1 # Manual increment
return results
processed_data = process_list_unpythonic(numbers)
print(processed_data)
Step 1: Refactor the Loop and Conditions
The first and most obvious improvement is to replace the manual while
loop with a direct for
loop (as we learned in Post #114) and combine the nested if
statements with and
.
def process_list_better(data):
results = []
for num in data:
# Combine the conditions
if num > 0 and num % 2 == 0:
square = num ** 2
line = "The square of " + str(num) + " is " + str(square)
results.append(line)
return results
This is already much better, safer, and easier to read.
Step 2: Refactor the String Formatting
Next, let’s replace the messy string concatenation with a clean and readable f-string (Post #115) and perform the calculation directly inside it.
def process_list_even_better(data):
results = []
for num in data:
if num > 0 and num % 2 == 0:
# Use a modern f-string
line = f"The square of {num} is {num**2}"
results.append(line)
return results
This is a huge improvement in readability.
Step 3: The Final Refactoring – A List Comprehension
This is the ultimate Pythonic step. Our entire for
loop is a classic “transform and filter” pattern. As we learned in Post #121, this is a perfect candidate for a list comprehension.
def process_list_pythonic(data):
"""Processes a list of numbers in a Pythonic way."""
return [f"The square of {num} is {num**2}" for num in data if num > 0 and num % 2 == 0]
# Let's run the final version
processed_data = process_list_pythonic(numbers)
print(processed_data)
The output is the same as our original script, but the implementation is vastly superior:
[‘The square of 2 is 4’, ‘The square of 6 is 36’, ‘The square of 8 is 64’, ‘The square of 10 is 100’]
This single line of code is more readable, more efficient, and perfectly expresses the logic of our task.
Congratulations and What’s Next for Part 6
Fantastic! You’ve not only learned what “Pythonic” code is, but you’ve also practiced the valuable skill of refactoring. This ability to see a verbose block of code and transform it into a clean, idiomatic solution is a key skill of an experienced Python developer.
So far, all of our programs have “forgotten” everything the moment they finish running. The data we create lives only in memory. To build truly persistent applications, we need to be able to save data to and read data from files.
In Part 6: File Handling and Error Management, we will learn how to make our programs interact with the file system, and how to gracefully handle the errors that can occur when things go wrong.
Author

Experienced Cloud & DevOps Engineer with hands-on experience in AWS, GCP, Terraform, Ansible, ELK, Docker, Git, GitLab, Python, PowerShell, Shell, and theoretical knowledge on Azure, Kubernetes & Jenkins. In my free time, I write blogs on ckdbtech.com