Skip to content

ይህ ትምህርት ገና ወደ አማርኛ አልተተረጎመም፤ ስለዚህ በእንግሊዝኛ ቀርቧል። የእንግሊዝኛውን ገጽ ክፈቱ

Looping patterns

3 min read

You can loop over a list. But real loops often need a little more: the position as well as the item, two lists at once, or the items in a different order. Python has a built-in for each of these, and each one makes a loop shorter and harder to get wrong. This lesson also covers the loop bug that skips items without any error.

Numbering with enumerate()

To print a numbered list, you could keep a counter yourself, as in Module 3. does it for you: each round it gives a pair, the position and the item, ready to unpack (lesson 4.3).

runners = ["Tigist", "Abel", "Meron"]
for position, name in enumerate(runners, start=1):
    print(f"{position}. {name}")

In the editor, press Escape then Tab to move on.

Without start=1 it counts from 0, like indexes. Remove it and see. If you forget enumerate altogether, Python tries to unpack each name:

Two lists together with zip()

When two lists line up, item by item, zip() walks them together. Each round gives one item from each:

items = ["teff", "coffee", "sugar"]
prices = [1200, 450, 90]
for item, price in zip(items, prices):
    print(f"{item}: {price} birr")

In the editor, press Escape then Tab to move on.

What if one list is shorter? Predict.

ውጤቱን ገምቱ

Decide before you look. Guessing wrong is how this sticks.

names = ["Hana", "Abel", "Selam"]
scores = [88, 92]
for name, score in zip(names, scores):
    print(name, score)
Pick the output

Python prints

Hana 88
Abel 92

zip stops as soon as the shorter list runs out, without a word. Selam has no score, so she's silently left out.

That silence can hide a bug: if a score is missing, nothing tells you. When the lists should match, check len() of both first.

Another order: reversed() and sorted()

reversed() goes through a list backwards, and sorted() (lesson 4.2) goes through it in order. Neither changes the list:

for n in reversed([1, 2, 3]):
    print(n)
names = ["Selam", "Abel", "Hana"]
for name in sorted(names):
    print(name)
print(names)

In the editor, press Escape then Tab to move on.

in instead of a flag

To ask "is Selam registered?" you could loop with a flag: start it False, and set it True when you find her.

registered = ["Hana", "Selam", "Abel"]
found = False
for name in registered:
    if name == "Selam":
        found = True
print(found)
print("Selam" in registered)

In the editor, press Escape then Tab to move on.

The last line asks the same question with in. When all you want to know is "is it there?", use in. Keep the flag loop for when you need to do more along the way.

Don't remove while you loop

You want to remove every 2 from a list. This looks right. Predict what it prints.

ውጤቱን ገምቱ

Decide before you look. Guessing wrong is how this sticks.

nums = [1, 2, 2, 3]
for n in nums:
    if n == 2:
        nums.remove(n)
print(nums)
Pick the output

Python prints

[1, 2, 3]

No error, but one 2 survives. Removing an item moves the rest of the list one place left, while the loop moves on to the next position, so it jumps over the item that slid into the gap.

Step through it and watch n. After the first 2 is removed, the loop's next value is 3: the second 2 was never looked at.

The skipped 2

Press Next to run one line at a time and watch each name change.

nums = [1, 2, 2, 3]
for n in nums:
if n == 2:
nums.remove(n)
print(nums)
Names and their values after line 1
NameValue after line 1
nums[1, 2, 2, 3]new
nnot made yet

Output so far

Step 1 of 10

Step 1 of 10. Line 1: nums = [1, 2, 2, 3]. nums is now [1, 2, 2, 3].

ጥያቄ

Why was the second 2 skipped?

Two fixes. Collect the items you want to keep into a new list (the collect plan from lesson 4.2), or loop over a copy, nums[:], and remove from the original:

nums = [1, 2, 2, 3]
kept = []
for n in nums:
    if n != 2:
        kept.append(n)
print(kept)

nums = [1, 2, 2, 3]
for n in nums[:]:
    if n == 2:
        nums.remove(n)
print(nums)

In the editor, press Escape then Tab to move on.

A slice makes a new list, so the loop walks the copy while the original changes.

መልመጃ

Rank the exam scores

Print the scores from highest to lowest, each with its position, starting at 1.

Output
1. 91
2. 82
3. 67
4. 45

Your code

scores = [67, 91, 45, 82]
# Sort from highest, then number each score with enumerate

In the editor, press Escape then Tab to move on.

መፍትሄውን አሳይ

This is one way to solve it, not the only one. If yours prints the same thing, it works.

scores = [67, 91, 45, 82]
for position, score in enumerate(sorted(scores, reverse=True), start=1):
    print(f"{position}. {score}")

ዋና ዋና ነጥቦች

  • enumerate(items, start=1) gives each item with its position: for position, name in ....
  • zip(a, b) walks two lists together and quietly stops at the shorter one.
  • reversed() and sorted() loop in another order without changing the list.
  • x in items answers "is it there?" without a flag loop.
  • Never remove from a list while looping over it: collect what to keep, or loop over a copy.