Skip to content

    Chapter 15, Basic

    Loops with for

    The `for` iterates over any collection. Almost whenever you think about counting indices, there is a better way to write it.

    Code for this chapter: basico/cap15_laco_for.py

    for in any iterable

    The for in Python does not count: it iterates over the items of any iterable object (string, list, file, dictionary):

    basico/cap15_laco_for.pylinhas 10 a 14
    for letra in "abc":
        print(letra)
    
    for fruta in ["maçã", "pera"]:
        print(fruta)
    
    Output
    a
    b
    c
    maçã
    pera
    

    range

    When you need a sequence of numbers, use range. It accepts range(fim), range(inicio, fim) and range(inicio, fim, passo), and the end is never included. It is lazy: it does not create the list in memory. The list() below serves only to show the content:

    basico/cap15_laco_for.pylinhas 19 a 22
    print(list(range(5)))
    print(list(range(1, 6)))
    print(list(range(0, 10, 2)))
    print(list(range(5, 0, -1)))
    
    Output
    [0, 1, 2, 3, 4]
    [1, 2, 3, 4, 5]
    [0, 2, 4, 6, 8]
    [5, 4, 3, 2, 1]
    

    enumerate and zip

    Do not write for i in range(len(lista)) to get the position. The enumerate delivers position and item together. The zip iterates two sequences in parallel:

    basico/cap15_laco_for.pylinhas 27 a 33
    nomes = ["Ana", "Bia", "Caio"]
    for posicao, nome in enumerate(nomes, start=1):
        print(posicao, nome)
    
    notas = [9, 8, 7]
    for nome, nota in zip(nomes, notas):
        print(f"{nome}: {nota}")
    
    Output
    1 Ana
    2 Bia
    3 Caio
    Ana: 9
    Bia: 8
    Caio: 7
    

    break, continue and else

    The break ends the loop. The continue skips to the next iteration. The else of the loop is little known and very useful: it runs only if the loop finished without break.

    basico/cap15_laco_for.pylinhas 38 a 45
    for numero in range(1, 11):
        if numero == 3:
            continue
        if numero == 6:
            break
        print(numero)
    else:
        print("terminou sem break")
    
    Output
    1
    2
    4
    5
    

    The else The loop shines in searches. To know if a number is prime, look for a divisor. If you find one, break. If the loop ends without finding one, the else confirms:

    basico/cap15_laco_for.pylinhas 47 a 53
    numero = 17
    for divisor in range(2, numero):
        if numero % divisor == 0:
            print(f"{numero} não é primo")
            break
    else:
        print(f"{numero} é primo")
    
    Output
    17 é primo
    

    Nested loops and patterns

    A loop inside another executes the inner one completely on each turn of the outer. It is the basis of tables, matrices, and patterns drawn with text:

    basico/cap15_laco_for.pylinhas 58 a 59
    for linhas in range(1, 5):
        print("*" * linhas)
    
    Output
    *
    **
    ***
    ****
    
    basico/cap15_laco_for.pylinhas 61 a 64
    for i in range(1, 4):
        for j in range(1, 4):
            print(f"{i} x {j} = {i * j}", end="  ")
        print()
    
    Output
    1 x 1 = 1  1 x 2 = 2  1 x 3 = 3  
    2 x 1 = 2  2 x 2 = 4  2 x 3 = 6  
    3 x 1 = 3  3 x 2 = 6  3 x 3 = 9  
    

    Multiplying a string by an integer ("*" * 3) repeats the text, and it is the trick that avoids a second loop in many designs.

    Exercise 1

    Factorial

    Write fatorial(n) with a loop for. The factorial of 0 is 1.

    Exercise 2

    Diamond of asterisks

    Write diamante(n) that returns a list of lines. For n = 3, the result should be [" *", " ***", "*****", " ***", " *"].

    Exercise 3

    Primes up to n

    Write primos_ate(n) with a loop inside another and the else of the for.