Arjan Egges reveals nested loops are design flaws, not algorithmic errors
Refactoring beyond the algorithmic surface
Arjan Egges argues that messy, deeply nested code is rarely an optimization problem. Instead, it serves as a glaring symptom of structural debt. When you find yourself iterating through orders inside a customer loop, you aren't just writing slow code; you're performing a manual database join in memory because your data structures are misaligned. This tutorial demonstrates how to refactor such "symptoms" using Pythonic principles and clean architecture.
Prerequisites
To follow this guide, you should be comfortable with Python fundamentals, including list comprehensions and dictionaries. Understanding basic Object-Oriented Programming (OOP) concepts like classes and methods is essential for the behavior placement section.
Key Libraries and Tools
- Python Standard Library: No external dependencies are required, as we leverage built-in types like
dictandlist. - Decimal Module: Highly recommended for financial calculations to avoid floating-point errors.
Eliminating implicit joins with dictionaries
Scanning every order for every customer creates an $O(n^2)$ complexity nightmare. By grouping data into a dictionary first, you trade memory for a massive speed boost and flatter code.

def group_orders_by_customer(orders):
orders_by_customer = {}
for order in orders:
orders_by_customer.setdefault(order.customer_id, []).append(order)
return orders_by_customer
By calling this function once, you replace a nested for loop with a constant-time lookup: customer_orders = orders_by_customer.get(customer.id, []).
Placing behavior in the right domain
A common mistake is performing low-level calculations, like summing order items, inside a high-level report generator. This logic belongs inside the Order class itself. Moving this behavior simplifies the caller and respects the object's boundaries.
@property
def total(self):
return sum(item.price * item.quantity for item in self.items)
Syntax Notes
We utilize the @property decorator to make the total calculation feel like an attribute access rather than a method call. Furthermore, Python's sum() function paired with a generator expression provides a cleaner alternative to manual loop accumulators.
Tips and Gotchas
- Incremental Growth: Messy code often starts with just "one more if statement." Review your nesting depth every time you add logic.
- Single Responsibility: If a function changes for more than one reason (e.g., the discount logic changes and the report format changes), it is doing too much. Split it into discrete helpers like
apply_discountandbuild_summary.
- Python
- 40%· products
- Arjan Egges
- 20%· people
- Order
- 20%· products
- Software Design Mastery
- 20%· products

Nested Loops Aren’t the Problem. This Is.
WatchArjanCodes // 15:23
On this channel, I post videos about programming and software design to help you take your coding skills to the next level. I'm an entrepreneur and a university lecturer in computer science, with more than 20 years of experience in software development and design. If you're a software developer and you want to improve your development skills, and learn more about programming in general, make sure to subscribe for helpful videos. I post a video here every Friday. If you have any suggestion for a topic you'd like me to cover, just leave a comment on any of my videos and I'll take it under consideration. Thanks for watching!