Skip to content

for-loop

Sequences are iterables, which means they naturally support for loop.

A for loop walks through the items of a sequence one item per iteration.

scores = [89, 49, 94]
for score in scores:
    print(score)

You don't manage a counter or an exit condition. The loop ends when the items run out, or is interrupted by a break statement.

If you only want to repeat an operation a given number of times, range() is enough:

# prompt the user for the password 3 times
password = 'secret'
for _ in range(3):
    if password == input('Please enter your password: '):
        print('Access granted')
        break
else:
    print('Access denied')

The else in the previous code snippet is not an error. It follows the for statement, not the if statement. That is, the body of that else clause will only run if the loop terminates normally, in this case, if the user fails to enter the correct password after 3 attempts.

Use enumerate() if you want the items positions:

names = ['Ada', 'Turing', 'Newman']
for pos, name in enumerate(names):
    print(f"{pos}: {name}")

Note that in the previous example, pos and name are assigned using unpacking.

The same can be achieved using range():

for pos in range(len(names)):
    print(f"{pos}: {names[pos]}")

As you can see, the enumerate() version is much cleaner.

Listing items of a sequence is not all that interesting. Instead, you often want to compute something from the sequence. This may include generating a new sequence, filtering, searching, aggregating, etc.

scores = [89, 49, 94, 50]
passing = []
for score in scores:
    if score >= 50:
        passing.append(score)
# count vowels in a string
text = "programming"
vowels = 0
for ch in text:
    if ch in "aeiou":
        vowels += 1
print(vowels)             # ⇒ 3

If the list contains only numeric values, the built-in functions such as min(), max(), sum(), and len() allow you to compute aggregates without needing a for loop.

scores = [89, 49, 94, 50]
avg = sum(scores) / len(scores)

break and continue

These work just as they do for while loops:

# stop at the first negative number
for n in [3, 8, -1, 5]:
    if n < 0:
        break             # leave the loop now
    print(n)              # ⇒ 3  8

# skip blanks, process the rest
for line in ["a", "", "b"]:
    if line == "":
        continue          # skip to next item
    print(line)           # ⇒ a  b

List comprehensions

A comprehension is a compact way to build a list by transforming or filtering another sequence. You can think of it as a shorthand for building a list using a loop.

# squares of 0..4
squares = [n * n for n in range(5)]          # ⇒ [0, 1, 4, 9, 16]

# with a filter
evens = [n for n in range(10) if n % 2 == 0] # ⇒ [0, 2, 4, 6, 8]

# transform 
names = ["ada", "grace"]
caps = [name.upper() for name in names]      # ⇒ ['ADA', 'GRACE']

Don't overdo it

Lists comprehensions shine best when they are kept simple. Start by writing the loop version and extract your list construction logic. If it needs more than one if or is getting too long, a regular loop is often the better idea.