SECTION 1
Historical Context & Motivation
Since the earliest days of computing, programmers have needed to take collections of data and produce new collections from them. Imagine a teacher who has a gradebook full of raw scores and needs a separate list of only the passing grades, or a game developer who has a list of all player positions and needs to extract only the ones inside a certain zone. These tasks — transforming data (changing every item) and filtering data (keeping only items that meet a condition) — are two of the most common operations in all of programming.
1958 • LISP Introduces map & filter
map) and keeping only elements that pass a test (filter). These concepts became foundational in computer science.1991 • Python Is Born
for loops made iterating through lists intuitive, even for beginners.2000 • List Comprehensions Added to Python
Today • Data Pipelines Everywhere
The central question this lesson addresses is straightforward: How do you take an existing list and produce a brand-new list that contains only the items you want, possibly changed in some way? The answer lies in a simple, repeatable loop pattern that you can use for almost any list-processing task.
SECTION 2
Core Principles & Definitions
Before diving into code, let's pin down the key ideas. Every transform-or-filter task follows the same three-part recipe: start with a source list, loop through it, and build a result list. Understanding these principles will make writing the code feel automatic.
The Accumulator Pattern
append() items to it. After the loop, the new list holds your results.Transforming (Mapping)
Filtering (Selecting)
if statement inside the loop to test each item. Only append items that pass the condition.Transform + Filter Combined
Non-Destructive Processing
KEY TAKEAWAY
SECTION 3
Visual Explanation — The Accumulator Loop
if condition. Only elements that pass (the even numbers 8, 12, and 6) are appended to the result list. The original list remains untouched.Notice the three stages in the diagram above. First, the source list feeds items one at a time into the loop. Second, the if condition acts as a gate, letting some items through and blocking others. Third, the items that pass are collected in the result list via append(). This three-stage structure is the same whether you're filtering numbers, strings, or any other data type.
SECTION 4
How It Works — The Code Patterns
Pattern 1: Transform Every Item
When you want to transform every item in a list (also called mapping), you apply an operation to each element and store the result. The skeleton looks like this:
TRANSFORM PATTERN
Where source is the original list, item is each element in turn, and f(item) is whatever operation you perform (e.g., item * 2 or item.upper()).
Pattern 2: Filter Items by Condition
When you want to filter a list, you include an if statement inside the loop. Only items that satisfy the condition are appended.
FILTER PATTERN
Where condition(item) is a Boolean expression, such as item > 0 or len(item) >= 5.
Pattern 3: Filter + Transform Combined
FILTER + TRANSFORM PATTERN
First test, then transform. This way the new list contains only the items you want, already in their new form.
Common Mistake
result = [] inside the loop, it resets on every iteration and you'll end up with only the last item.SECTION 5
Patterns in Action — Real Code Examples
prices, multiplies it by 2, and appends the result to doubled. The original list stays untouched.Let's see the full Python code for both a transform and a filter example. Study the structure carefully — the skeleton is the same every time.
| Transform Example | Filter Example |
|---|---|
names = ["alice", "bob", "cara"]
upper_names = []
for n in names:
upper_names.append(n.upper())
# ["ALICE", "BOB", "CARA"] | scores = [88, 42, 95, 67, 73]
passing = []
for s in scores:
if s >= 70:
passing.append(s)
# [88, 95, 73] |
Side-by-side comparison of the transform and filter patterns
In the transform example on the left, every name is converted to uppercase and placed in the new list. In the filter example on the right, only scores of 70 or above make it into passing. The key difference is the presence or absence of an if statement inside the loop.
SECTION 6
Worked Example — Filter & Transform a Grade List
Suppose you have a list of student percentages and you need to produce a new list containing only the grades above 60, converted to letter grades using a simple rule: 90+ → 'A', 80–89 → 'B', 70–79 → 'C', 60–69 → 'D'. Let's walk through the full solution.
Build a List of Passing Letter Grades
- 1
Step 1 — Define the source data
We start with a list of raw percentages:grades = [92, 55, 78, 83, 41, 67, 95]. This is our source list that we will loop through. - 2
Step 2 — Create the empty result list
Before the loop, initialize the accumulator:letter_grades = []. This list will hold only passing letter grades.letter_grades = [] - 3
Step 3 — Write the loop with the filter condition
We iterate withfor g in grades:and immediately checkif g > 60:. This filters out the failing scores (55 and 41). - 4
Step 4 — Transform passing scores to letters
Inside theifblock, we useif/elifto convert the numeric grade to a letter. For example, 92 becomes 'A', 78 becomes 'C', and 67 becomes 'D'. We then append the letter toletter_grades. - 5
Step 5 — Verify the result
After the loop completes,print(letter_grades)outputs the final list. The originalgradeslist is unchanged.["A", "C", "B", "D", "A"]— only the 5 passing grades, converted to letters
Full Code
grades = [92, 55, 78, 83, 41, 67, 95]
letter_grades = []
for g in grades:
if g > 60:
if g >= 90:
letter_grades.append("A")
elif g >= 80:
letter_grades.append("B")
elif g >= 70:
letter_grades.append("C")
else:
letter_grades.append("D")
print(letter_grades) # ["A", "C", "B", "D", "A"]SECTION 7
Strengths & Limitations of Loop-Based Patterns
The loop-based accumulator pattern is a powerful tool, but like any technique, it has trade-offs. Understanding when it shines and when alternatives might be better will make you a more thoughtful programmer.
| Strengths ✅ | Limitations ⚠️ |
|---|---|
| Easy to read and understand — the logic flows line by line. | Can be verbose for simple operations (more lines of code than a list comprehension). |
| Fully flexible — you can combine filtering, transforming, and complex logic in one loop. | For very large data sets, Python loops can be slow compared to built-in functions optimized in C. |
| Easy to debug — you can add print statements inside the loop to inspect each iteration. | If you accidentally modify the source list instead of building a new one, bugs can be hard to track down. |
| Works with any iterable, not just lists — strings, files, ranges, and more. | Experienced Python developers often prefer list comprehensions for brevity, so you'll need to learn those too. |
Strengths and limitations of the loop-based accumulator pattern
KEY TAKEAWAY
map() and filter() are like automatic transmission — faster to use once you understand what's happening under the hood. Master the manual version first.SECTION 8
Connection to List Comprehensions & Beyond
Once you're comfortable with loop-based patterns, you'll be ready to learn list comprehensions — Python's compact, one-line way to do the same thing. A list comprehension packs the loop, the condition, and the transformation into a single expression. Understanding the loop pattern first makes comprehensions feel natural rather than magical.
| Loop-Based Pattern (This Lesson) | List Comprehension (Next Step) |
|---|---|
result = []
for x in nums:
result.append(x * 2) | result = [x * 2 for x in nums] |
result = []
for x in nums:
if x > 0:
result.append(x) | result = [x for x in nums if x > 0] |
| Multiple lines, easy to debug, great for complex logic | One line, concise, Pythonic — best for simple transforms/filters |
Side-by-side: loop patterns vs. list comprehensions
Beyond list comprehensions, Python offers built-in functions like map() and filter(), as well as powerful libraries like pandas for data science. All of these higher-level tools do the same fundamental thing your loop does: iterate over a collection, optionally test each item, optionally transform it, and collect the results. The pattern you learned today is the foundation for all of them.
SECTION 9
Practice Problems
Question 1: CONCEPTUAL
result = [] inside the for loop?Show answer
result = [] inside the loop, the list is reset to empty on every iteration. This means each pass through the loop wipes out everything that was previously appended. After the loop finishes, result would contain only the last item processed (if it was appended) or would be empty. By creating the list before the loop, we ensure that append() accumulates values across all iterations.Question 2: BASIC CALCULATION
temps_f = [32, 68, 212, 98.6, 50], write a loop that builds a new list temps_c containing each temperature converted to Celsius using the formula C = (F − 32) × 5 / 9. What does temps_c contain?Show answer
temps_c = [] followed by for f in temps_f: and temps_c.append((f - 32) * 5 / 9). Each Fahrenheit value is transformed: 32°F → 0.0°C, 68°F → 20.0°C, 212°F → 100.0°C, 98.6°F → 37.0°C, and 50°F → 10.0°C. The result is [0.0, 20.0, 100.0, 37.0, 10.0]. This is a pure transform pattern — no filtering needed since every temperature is converted.Question 3: INTERMEDIATE
words = ["hello", "I", "am", "a", "Python", "programmer"], write a loop that builds a new list long_upper containing only the words with 4 or more characters, converted to uppercase. What is the output?Show answer
long_upper = [], then for w in words: with if len(w) >= 4: and long_upper.append(w.upper()). The filter condition len(w) >= 4 eliminates "I", "am", and "a". The remaining words are transformed to uppercase: "hello" → "HELLO", "Python" → "PYTHON", "programmer" → "PROGRAMMER". The final result is ["HELLO", "PYTHON", "PROGRAMMER"].Question 4: APPLIED
students = [["Ana", 91], ["Ben", 64], ["Cho", 88], ["Dex", 55], ["Eva", 76]]. Write a loop that builds a new list honor_roll containing only the names (not scores) of students who scored 80 or above.Show answer
honor_roll = [], then for student in students: with if student[1] >= 80: and honor_roll.append(student[0]). Here student[1] accesses the score for filtering, and student[0] accesses the name for the result. Ana (91) and Cho (88) qualify, so honor_roll becomes ["Ana", "Cho"]. This demonstrates that you can filter on one part of the data and collect a different part.Question 5: CRITICAL THINKING
nums = [3, -1, 4, -5, 2] followed by for n in nums: and if n < 0: nums.remove(n). They report that it sometimes misses negative numbers. Explain why this approach is buggy and how building a new list solves the problem.Show answer
nums.remove(n) removes an element, the remaining elements shift left, but the loop's internal index still advances. This causes the loop to skip the element that slid into the position of the removed item. For example, after removing −1 at index 1, the value 4 shifts from index 2 to index 1, but the loop moves to index 2, which is now −5. If two negatives are adjacent, one will be skipped. The correct approach is the accumulator pattern: positives = [], for n in nums: if n >= 0: positives.append(n). Building a new list avoids mutating the collection you're iterating over, eliminating the bug entirely.SUMMARY
Lesson Summary
Summary
In this lesson you learned the accumulator pattern — a reliable recipe for building a new list from an existing one. The pattern has three steps: create an empty result list before the loop, iterate through the source list with a for loop, and use append() to add items to the result. For transforming, you modify each item before appending. For filtering, you use an if statement to decide which items make the cut. You can combine both in a single loop.
This pattern is non-destructive — the original list remains intact, which prevents subtle bugs caused by modifying data in place. As you advance, you'll see that list comprehensions and built-in functions like map() and filter() are shorthand for the exact same loop-based logic. Mastering the explicit loop first gives you the foundation to understand — and debug — every future tool you encounter.