COMPUTER PROGRAMMING 1 (PYTHON) • CORE DATA STRUCTURES

Transforming & Filtering Lists — I can transform/filter a list using loop-based patterns (build a new list) at my level.

Learn to build new lists by looping through existing ones, selecting and reshaping data along the way.

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
John McCarthy's LISP language formalized the idea of applying a function to every element in a list (map) and keeping only elements that pass a test (filter). These concepts became foundational in computer science.
1991
Python Is Born
Guido van Rossum released Python, emphasizing readability. Python's for loops made iterating through lists intuitive, even for beginners.
2000
List Comprehensions Added to Python
Python 2.0 introduced list comprehensions — a compact syntax inspired by mathematical set notation. However, the underlying loop-based pattern remains the clearest way for beginners to learn the concept.
Today
Data Pipelines Everywhere
Modern applications — from social media feeds to scientific data analysis — constantly transform and filter massive lists. Mastering loop-based patterns gives you the mental model behind all of these tools.

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.

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.

1

The Accumulator Pattern

Create an empty list before the loop. Inside the loop, append() items to it. After the loop, the new list holds your results.
2

Transforming (Mapping)

Apply some operation to each item — for example, doubling every number or converting every string to uppercase — and add the changed item to the new list.
3

Filtering (Selecting)

Use an if statement inside the loop to test each item. Only append items that pass the condition.
4

Transform + Filter Combined

You can filter first and then transform, or do both at once inside the same loop. This is incredibly common in real programs.
5

Non-Destructive Processing

Building a new list means the original list stays unchanged. This is important because other parts of your program may still need the original data.
✦ KEY TAKEAWAY
Think of the accumulator pattern like packing a suitcase for a trip. You start with an empty suitcase (the new list). You look at every item in your closet (the source list). For each item, you decide whether it goes in the suitcase and maybe fold it differently (transform). When you're done, you have a packed suitcase — a new, purpose-built collection — and your closet is untouched.

Visual Explanation — The Accumulator Loop

The diagram shows the filtering pattern. Each element of the source list is tested by the 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.

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
result = [] for item in source: result.append( f(item) )
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
result = [] for item in source: if condition(item): result.append(item)
Where condition(item) is a Boolean expression, such as item > 0 or len(item) >= 5.

Pattern 3: Filter + Transform Combined

FILTER + TRANSFORM PATTERN
result = [] for item in source: if condition(item): result.append( f(item) )
First test, then transform. This way the new list contains only the items you want, already in their new form.
⚠️ Common Mistake
Don't forget to create the empty list before the loop! If you write result = [] inside the loop, it resets on every iteration and you'll end up with only the last item.

Patterns in Action — Real Code Examples

This diagram traces a transform loop that doubles each price. Each iteration takes one value from 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.

Side-by-side comparison of the transform and filter patterns
Transform ExampleFilter 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]

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.

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 dataWe 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 listBefore 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 conditionWe iterate with for g in grades: and immediately check if g > 60:. This filters out the failing scores (55 and 41).
4
Step 4 — Transform passing scores to lettersInside the if block, we use if/elif to convert the numeric grade to a letter. For example, 92 becomes 'A', 78 becomes 'C', and 67 becomes 'D'. We then append the letter to letter_grades.
5
Step 5 — Verify the resultAfter the loop completes, print(letter_grades) outputs the final list. The original grades list 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"]

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 and limitations of the loop-based accumulator pattern
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.
✦ KEY TAKEAWAY
The loop-based pattern is like a manual transmission in a car — it gives you full control over every gear shift, making it perfect for learning. List comprehensions and built-in functions like map() and filter() are like automatic transmission — faster to use once you understand what's happening under the hood. Master the manual version first.

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.

Side-by-side: loop patterns vs. list comprehensions
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 logicOne line, concise, Pythonic — best for simple transforms/filters

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.

Practice Problems

PROBLEM 1 — CONCEPTUAL
In your own words, explain why we create an empty list before the loop instead of inside it. What would happen if we placed result = [] inside the for loop?
PROBLEM 2 — BASIC CALCULATION
Given 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?
PROBLEM 3 — INTERMEDIATE
Given 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?
PROBLEM 4 — APPLIED
A school stores student data as a list of lists: 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.
PROBLEM 5 — CRITICAL THINKING
A classmate writes this code to remove negative numbers from a list: 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.

Lesson 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.

Varsity Tutors • Computer Programming 1 (Python) • Transforming & Filtering Lists