2.13. Controle de laço

Duas palavras-chave alteram a forma como um laço é executado:

  • break – sai do laço imediatamente.

  • continue – pula o restante da iteração atual e inicia a próxima.

Ambas se aplicam ao laço mais interno em que aparecem.

2.13.1. break

Use break para parar um laço assim que uma condição for satisfeita. O padrão clássico de “buscar e parar”:

found = None
for item in items:
    if matches(item):
        found = item
        break

if found is not None:
    print("found:", found)

Em um laço while True:, o break é a forma como o laço termina:

while True:
    line = next_line()
    if line == "quit":
        break
    process(line)

2.13.2. continue

Use continue para pular o restante do corpo e saltar para a próxima iteração. Útil para filtrar itens dentro de um laço:

for n in numbers:
    if n < 0:
        continue            # skip negatives
    print(n)

O mesmo efeito pode ser escrito como um bloco if em torno do restante do corpo. O continue às vezes é mais claro quando a condição de pular é mais fácil de enunciar de imediato do que a condição de manter.

Dentro de um laço, o continue desempenha o mesmo papel que um return antecipado em uma função: pula os casos que você não trata e mantém o trabalho principal sem aninhamento, no recuo externo. O laço de filtrar e processar é a forma canônica:

for item in items:
    if item is None:
        continue
    if not item.is_valid():
        continue
    process(item)

A linha recuada process(item) é o trabalho real; cada guarda acima especifica exatamente quais itens são pulados.

2.13.3. else em um laço

Tanto for quanto while aceitam um bloco else opcional. Ele é executado quando o laço termina sem atingir um break. O uso mais comum é um laço de busca que quer um valor de reserva caso nada seja encontrado:

for item in items:
    if matches(item):
        print("found:", item)
        break
else:
    print("no match")

Se um break for disparado, o bloco else é pulado. Leia a construção como “for X in Y: …; ou então, se nunca saímos, faça Z.”

2.13.4. Padrões comuns de laço

Alguns padrões aparecem com frequência em scripts reais:

  • Polling – aguardar que alguma condição se torne verdadeira antes de prosseguir. O corpo usa pass, a instrução nula do Python; todo bloco recuado precisa conter pelo menos uma instrução, e o pass é a forma de dizer “não fazer nada aqui”:

    while not ready():
        pass
    proceed()
    
  • Máquina de estados – um único laço while True: que escolhe o que fazer com base em uma variável de estado. Útil quando o trabalho se divide claramente em algumas fases nomeadas:

    state = "header"
    for line in lines:
        if state == "header":
            if line.startswith("---"):
                state = "body"
        elif state == "body":
            print(line)
    
  • Acumulação – construir um resultado enquanto percorre uma sequência:

    total = 0
    for x in samples:
        total += x
    mean = total / len(samples)
    

    Muitos laços de acumulação têm um equivalente de uma linha usando uma função embutida. Recorra à função embutida quando alguma se aplicar:

    • sum() – soma todos os itens de um iterável.

    • max() / min() – o maior ou o menor item.

    • any()True se pelo menos um item for verdadeiro.

    • all()True somente quando todos os itens forem verdadeiros.

    • sorted() – uma nova lista com os itens em ordem.

    • len() – o número de itens (quando o iterável conhece seu comprimento).

    >>> samples = [3, 1, 4, 1, 5, 9, 2, 6]
    >>> sum(samples)
    31
    >>> sum(samples) / len(samples)        # mean
    3.875
    >>> max(samples)
    9
    >>> min(samples)
    1
    >>> sorted(samples)
    [1, 1, 2, 3, 4, 5, 6, 9]
    >>> any([False, False, True])
    True
    >>> all([True, True, False])
    False
    

    A versão embutida é mais curta, mais clara e geralmente mais rápida do que escrever o mesmo laço à mão.