Courseiva
PCEP-30-02Chapter 10 of 16Objective 3.5

Iterating Over Lists, Tuples, and Dictionaries

Without the ability to visit each item in a collection one by one, you would be forced to write repetitive, error-prone code that handles every element by hand. This chapter teaches you how to use loops to automatically process every element in lists, tuples, and dictionaries — a skill you will need in every PCEP-30-02 exam question about data structures. By the end, you will understand how to write a `for` loop that saves you hours of manual work.

12 min read
Intermediate
Updated Jul 23, 2026
Reviewed by Johnson Ajibi· Senior Network & Security Engineer · MSc IT Security

A simple way to picture Iterating Over Lists, Tuples, and Dictionaries

The 12-Item Grocery Bag Analogy

12 items are on your grocery list: 3 fruits (apple, banana, cherry), 4 frozen vegetables (peas, corn, spinach, broccoli), and 5 pantry staples (rice, pasta, oil, salt, sugar). You need to check each item one by one before paying at the self-checkout. You cannot grab the whole list at once. You must pick up each item, scan its barcode, and place it into a new bag. This is exactly what iteration does: you have a collection (the grocery list) and you process each element (the item) one time in order. If you skip an item or scan it twice, the total is wrong. Similarly, when iterating over a list in Python, the loop visits each element exactly once. For a dictionary, you might want to check either the product name (key) or its price (value). A tuple is like a frozen shopping list that cannot be changed mid-checkout. The loop moves from the first item to the last, just like you move along the conveyor belt. The analogy maps precisely: the grocery list is the data structure, each item is an element, the scanner action is the loop body, and the checkout total is the accumulated result. If you need to double-check an item, you must start the whole scan over again, teaching you that iterating goes in one direction unless you explicitly reset.

The 12 items force you to handle each one separately, just as a for loop forces you to handle each element in the collection individually. You cannot process them all at once because the scanner can only read one barcode per item. This mirrors Python’s for loop: one element per iteration.

How It Actually Works

Iterating means going through each item in a collection one at a time. In Python, collections like lists, tuples, and dictionaries hold multiple pieces of data. To work with each piece individually, you use a for loop. This is the most common way to iterate in Python. The for loop gives you a temporary variable that takes the value of the current element, runs a block of code once for that element, then moves to the next element until every element has been processed.

Let’s start with a list. A list is an ordered, changeable collection written inside square brackets, like fruits = ['apple', 'banana', 'cherry']. To iterate over it:

fruits = ['apple', 'banana', 'cherry']
for fruit in fruits:
    print(fruit)

The loop runs three times: first fruit = 'apple', then fruit = 'banana', then fruit = 'cherry'. It stops automatically. The variable name fruit is up to you — it holds a reference to the current element. The colon : starts the block of code that runs each iteration. The indented lines under the for statement define that block. Python uses indentation to group code, so every line that is indented at the same level belongs to the loop.

Tuples work almost identically. A tuple is written in parentheses, like coordinates = (10, 20, 30). Tuples are immutable — they cannot be changed after creation. The iteration is exactly the same:

coordinates = (10, 20, 30)
for coord in coordinates:
    print(coord)

Dictionaries are different. They store key-value pairs: each element has a unique key and an associated value. For example, student = {'name': 'Alice', 'age': 22, 'grade': 'A'}. To iterate over a dictionary, you can loop over its keys, values, or both. By default, iterating over a dictionary gives you the keys:

student = {'name': 'Alice', 'age': 22, 'grade': 'A'}
for key in student:
    print(key)  # prints name, age, grade

To get the values, use the .values() method:

for value in student.values():
    print(value)  # prints Alice, 22, A

To get both keys and values together as pairs, use the .items() method. This gives you a tuple of (key, value) for each iteration:

for key, value in student.items():
    print(f"{key}: {value}")

The f"" is an f-string, which lets you insert variables directly into the text. In this case, it prints "name: Alice", "age: 22", and so on.

Why does iteration exist? Before loops, you would have to write print(fruits[0]), print(fruits[1]), print(fruits[2]) for each element. That is fine for three fruits but impractical for a list of 10,000 customer names. Loops automate this repetition, making code shorter, easier to read, and less error-prone.

A critical rule: you cannot iterate over an integer or a floating-point number directly. Only sequences (like lists, tuples, strings) and mappings (dictionaries) support iteration. Attempting for x in 5: raises a TypeError.

Another important concept is the range() function. When you need to iterate a specific number of times, range() generates a sequence of numbers. For example, range(5) produces numbers 0, 1, 2, 3, 4. Combined with len(), you can iterate over a list by index:

fruits = ['apple', 'banana', 'cherry']
for i in range(len(fruits)):
    print(i, fruits[i])

This prints the index and the element. But using for fruit in fruits: is simpler and preferred unless you need the index.

You can also iterate over strings. A string is a sequence of characters. This loop prints each character:

word = 'hello'
for char in word:
    print(char)

Remember that dictionaries are unordered in older Python versions (before 3.7). In Python 3.7 and later, dictionaries preserve insertion order, but the exam may test that you must not rely on order if you are writing for compatibility. The PCEP-30-02 exam covers all these details.

Finally, you cannot modify a collection while iterating over it directly. If you try to delete an element from a list while you are iterating, you will skip elements or get errors. The safe way is to iterate over a copy (using [:] or list(original)) or collect items to remove and delete them after the loop.

Practice: write a loop that sums all numbers in a list [10, 20, 30]. You need an accumulator variable initialised to 0, then add each number inside the loop. This is a pattern you will use often.

Let’s summarise the types of iteration you will see in the exam:

Iterating over a list with for element in list:

Iterating over a tuple with for element in tuple:

Iterating over dict keys with for key in dict:

Iterating over dict values with for value in dict.values():

Iterating over dict key-value pairs with for key, value in dict.items():

Iterating over a string with for char in string:

Iterating with range() for numeric loops

Each of these is a common exam question. Know them by heart.

This flowchart shows how to choose the correct iteration method based on the type of collection you are working with, leading to the loop body execution.

Walk-Through

1

Identify the collection to iterate over

Determine whether you have a list, tuple, dictionary, or string. Each behaves differently: lists and tuples give you elements directly, dictionaries give keys by default, and strings give characters. This step is crucial because the loop structure is the same, but what you access inside changes.

2

Choose the correct loop construct

For PCEP-30-02, the `for` loop is the correct choice. Write `for variable_name in collection:` where `variable_name` is any valid Python identifier. The colon is mandatory. Python expects an indented block after it. If you forget the colon, you get a syntax error.

3

Write the loop body with indentation

Every line that runs during each iteration must be indented consistently (usually 4 spaces). Inside the loop body, you can access the loop variable (which holds the current element), perform operations, call functions, or accumulate results. The indentation tells Python where the loop ends.

4

Handle dictionary iteration explicitly

If you are iterating over a dictionary and you need values, use `.values()`. If you need both keys and values, use `.items()` with two loop variables separated by a comma. Default iteration gives only keys, which is often not what you want. This step prevents the common mistake of misreading dictionary data.

5

Avoid modifying the collection during iteration

If you need to remove elements from a list while iterating, do not delete them inside the loop. Instead, build a new list containing only the elements you want to keep, or iterate over a copy of the list (e.g., `for item in original_list[:]`). This step prevents subtle bugs that the exam loves to test.

6

Test the loop with a small example

Run the loop with a small dataset to verify it processes each element correctly. Use `print()` statements to inspect the loop variable at each iteration. Many exam questions ask you to predict output, so practising with small examples builds intuition for how the loop variable changes.

What This Looks Like on the Job

An IT professional working in e-commerce needs to generate a daily sales report. They have a list of sales amounts from yesterday, stored as a Python list: sales = [245.50, 189.99, 310.00, 150.75, 422.30]. They need to calculate the total revenue and identify which sales were above $200. Without iteration, they would have to manually add each number. With a loop, they write a few lines of code that automatically process all five (or five thousand) sales.

The process goes like this: first, the IT professional opens their Python script or Jupyter notebook. They define a variable total = 0 to hold the running total. Then they write a for loop:

for sale in sales:
    total += sale
    if sale > 200:
        print(f"Sale of ${sale:.2f} is above $200")

The += operator adds the current sale amount to the total. The if statement checks each sale. In one minute, the code produces the total and flags all high-value sales. This is vastly faster than doing it by hand.

Now imagine the company also stores product details in a dictionary: each product has a unique product ID as the key and its price as the value. The IT professional needs to apply a 10% discount to all products and output new prices. They can iterate over the dictionary items:

products = {'P001': 25.00, 'P002': 50.00, 'P003': 15.00}
for prod_id, price in products.items():
    discounted = price * 0.9
    print(f"{prod_id}: new price ${discounted:.2f}")

Notice that the original dictionary is not changed. If the professional needed to update the dictionary, they would need to write back into it carefully, because modifying a dictionary while iterating can cause errors. Instead, they might build a new dictionary.

Another real-world scenario: a system administrator has a list of server IP addresses stored as a tuple (because the list of servers should never change). They need to ping each server to check if it is online. The tuple servers = ('192.168.1.1', '192.168.1.2', '192.168.1.3') is iterated over, and each IP is passed to a ping function. If one server fails, the admin records it in a separate list. The immutability of the tuple guarantees that no code accidentally changes the server list.

What tools are used? - Python IDEs like PyCharm or VS Code for writing loops - Jupyter Notebooks for quick data analysis - time module to measure how long iteration takes (important for performance optimisation) - csv module to read files line by line, where each line is processed in a loop - pandas library for large-scale data manipulation (but the exam focuses on pure Python)

In practice, IT professionals often chain loops: first they iterate over a list of customer IDs, then inside that loop they iterate over a dictionary of orders for each customer. This is called nested iteration. For example, each customer ID from a list points to a dictionary of their orders, and the loop extracts the total per customer.

The step-by-step action in business:

Step 1: Collect data into a list, tuple, or dictionary from a database or file.

Step 2: Write a for loop to process each element.

Step 3: Inside the loop, perform calculations, condition checks, or output.

Step 4: Accumulate results in variables or new collections.

Step 5: Use the final result (e.g., send a report, update a database).

This is how real code works. The loop is the engine that drives most data processing in Python.

How PCEP-30-02 Actually Tests This

The PCEP-30-02 exam tests iteration over lists, tuples, dictionaries, and strings very directly. You will see multiple-choice questions that require you to predict the output of a for loop or identify the correct syntax. The examiners want to know you understand three things: how the loop variable works, how to access dictionary keys and values, and what happens when you try to iterate over unsupported types.

Here are the exact concepts they love to test:

The for loop syntax: for variable in sequence: followed by an indented block. They will present incorrect variants, like for variable in sequence (missing colon) or for sequence in variable (wrong order).

Iteration over strings: a string is a sequence of characters. They may give you for ch in 'abc': print(ch) and ask what prints. The answer is each character on a new line.

Iteration over dictionary keys by default: for k in dict: iterates over keys. They may ask what type the variable k is (string, int, etc.) based on the dictionary’s keys.

The .items() method returns tuples: for a, b in dict.items():. Traps include thinking .items() returns a dictionary or a list directly.

The .values() method returns an iterable of values. They may test whether .values() returns a list or a view object.

Modifying a collection while iterating is a trap. For example, a list with [1,2,3,4,5] and a loop that removes elements: the output is unpredictable. Expect a question that asks “What happens?” and the correct answer is “Unpredictable behaviour / elements may be skipped.”

The range() function: for i in range(5) produces 0 to 4. They may set range(1, 6) or range(0, 10, 2) and ask for the number of iterations.

Iterating over a tuple is similar to a list, but they may test that a tuple is immutable. You cannot assign a new value to an element inside the loop.

Nested loops: a loop inside another loop. They may give you a 2D list like matrix = [[1,2],[3,4]] and ask for the sum of all elements. The inner loop runs for each element of the outer loop.

Trap patterns to watch for:

They might provide a for loop with else clause. Python allows for...else where the else block runs if the loop completes normally (no break). They may ask what prints when the loop is empty or has a break.

They might use a variable name that already exists. For example, i = 10 and then for i in [1,2,3]: — the loop variable i overwrites the previous value. After the loop, i will be 3, not 10.

They might show a loop iterating over an empty list. The code inside the loop never runs, and any variable set inside the loop remains undefined (raises NameError).

They might test that iterating over a dictionary using for key, value in dict: (without .items()) raises a ValueError because unpacking a single key is not possible.

They may give you a string with spaces or punctuation and ask how many times the loop runs — it runs once per character, including spaces.

Key definitions to memorise:

Iteration: the process of visiting each element in a collection one by one.

Loop variable: the temporary variable that holds the current element during each iteration.

Sequence: an ordered collection that supports indexing (list, tuple, string).

View object: returned by .items(), .values(), .keys() — dynamic and reflect changes to the dictionary.

They will also test you on the break and continue statements. break terminates the loop prematurely. continue skips the rest of the current iteration and moves to the next one. For example, for x in [1,2,3,4]: if x == 3: break; print(x) prints 1 and 2 and then stops.

Practice with questions like: “How many times does this loop print?”, “What is the value of variable x after the loop?”, “Which of the following correctly iterates over keys of a dictionary?”. These are the typical exam formats.

Key Takeaways

The `for` loop in Python iterates over each element of a sequence exactly once, from first to last.

When iterating over a dictionary, the default loop variable holds the keys, not the values.

To get both keys and values from a dictionary in a loop, use the `.items()` method with two loop variables.

Tuples are immutable; you cannot reassign elements inside a for loop — attempting to do so raises a TypeError.

The `range()` function generates numbers that can be used in a for loop to repeat an action a specific number of times.

Modifying a list while iterating over it can cause skipped elements or runtime errors — iterate over a copy instead.

After a for loop completes, the loop variable retains the value of the last processed element.

Strings are iterable sequences of characters, so a for loop over a string processes one character per iteration.

Easy to Mix Up

These come up on the exam all the time. Here's how to tell them apart.

List

Mutable: can change, add, or remove elements after creation.

Defined with square brackets: [1, 2, 3].

Slightly slower for iteration due to overhead of mutability.

Tuple

Immutable: cannot change elements after creation.

Defined with parentheses: (1, 2, 3).

Slightly faster for iteration because the structure is fixed.

for key in dict:

Iterates only over the dictionary keys.

Loop variable holds a single key each iteration.

Cannot directly access values without an extra lookup: dict[key].

for key, value in dict.items():

Iterates over key-value pairs as tuples.

Loop variables hold the key and value separately.

Accesses both key and value directly without an extra lookup.

for char in string:

Directly gives each character.

No index variable available unless assigned separately.

Simpler and more readable for character-by-character processing.

for i in range(len(string)):

Iterates over a range of numbers (indices).

Gives you the index i to access string[i].

Useful when you need the position of each character.

Watch Out for These

Mistake

Iterating over a dictionary directly gives you both keys and values like .items() does.

Correct

Iterating over a dictionary directly gives you only the keys. To get both keys and values, you must call .items().

Beginners see console output from interactive Python that sometimes shows key-value pairs, but iteration always defaults to keys.

Mistake

You can change elements in a tuple by iterating over it and assigning new values.

Correct

Tuples are immutable. You cannot assign new values to elements. The assignment will raise a TypeError.

The concept of immutability is abstract. Beginners think a loop gives 'write access', but it does not—tuples are read-only.

Mistake

The loop variable retains the same value after the loop finishes as it had before the loop started.

Correct

After a for loop ends, the loop variable holds the last element from the sequence, overwriting any previous value.

This is counterintuitive because variables inside scope persist. Beginners expect variables to be local to the loop.

Mistake

When iterating over a list, the loop works on a copy of the list, so modifying the original list inside the loop is safe.

Correct

The loop works on the original list. Modifying (e.g., deleting) elements while iterating can skip elements or cause errors.

The visual analogy of a 'loop' sounds like a separate path, but it directly accesses the same list object in memory.

Mistake

You can iterate over an integer by using it directly in a for loop: for i in 5:

Correct

Integers are not iterable. You must use range(5) to generate a sequence of numbers.

Beginners see that 5 is a number and assume loops iterate over a count. The concept of iterability is not obvious.

Mistake

Dictionary .items() returns a list of tuples that you can modify without affecting the original dictionary.

Correct

.items() returns a view object that reflects the dictionary in real time. Modifying the view does not modify the dictionary directly, but the view updates as the dictionary changes.

View objects are an advanced concept. Beginners assume returning a list because it looks like one in some contexts.

Do You Actually Know This?

Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.

Frequently Asked Questions

Can I iterate over a number like 5 in a for loop?

No, integers are not iterable. You will get a TypeError. Use `range(5)` to generate a sequence of numbers you can iterate over.

What is the difference between iterating over a list and a tuple with a for loop?

The loop syntax is identical. The key difference is that tuples are immutable: you cannot change an element during iteration. Lists allow modification (though it is risky) while tuples forbid it.

How do I iterate over a dictionary and get both the key and value?

Use the `.items()` method inside the loop: `for key, value in dictionary.items():`. This gives you a tuple of (key, value) in each iteration.

What happens if I modify a list while iterating over it?

It can cause unpredictable behaviour: elements may be skipped or the loop may raise an error. It is safer to iterate over a copy of the list or collect items to remove and apply them after the loop.

Does a for loop create a new variable that exists only inside the loop?

No. The loop variable is created in the current scope and persists after the loop ends, holding the last element from the sequence. It can overwrite an existing variable with the same name.

Can I iterate over a string with a for loop?

Yes, strings are sequences of characters. A for loop over a string processes one character at a time, including spaces and punctuation.

Terms Worth Knowing

Keep going

You've finished Iterating Over Lists, Tuples, and Dictionaries. Continue through the PCEP-30-02 study guide to build a complete picture of the exam.

Done with this chapter?