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 opassé 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.any()–Truese pelo menos um item for verdadeiro.all()–Truesomente 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.