2.13. Controlo de ciclos¶
Duas palavras-chave alteram o funcionamento de um ciclo:
break– sai do ciclo imediatamente.continue– salta o resto da iteração atual e inicia a próxima.
Ambas se aplicam ao ciclo mais interior em que aparecem.
2.13.1. break¶
Use break para parar um ciclo assim que uma condição for satisfeita. O padrão clássico de «procurar e parar»:
found = None
for item in items:
if matches(item):
found = item
break
if found is not None:
print("found:", found)
Num ciclo while True:, o break é a forma de terminar o ciclo:
while True:
line = next_line()
if line == "quit":
break
process(line)
2.13.2. continue¶
Use continue para saltar o resto do corpo e passar para a próxima iteração. Útil para filtrar itens dentro de um ciclo:
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 resto do corpo. O continue é por vezes mais claro quando a condição de salto é mais fácil de enunciar do que a condição de manter.
Dentro de um ciclo, o continue desempenha o mesmo papel que um return antecipado numa função: saltar os casos que não se tratam e manter o trabalho principal nivelado no recuo exterior. O ciclo 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 process(item) com recuo é o trabalho efetivo; cada guarda acima especifica exatamente quais os itens que são ignorados.
2.13.3. else num ciclo¶
Tanto o for como o while aceitam um bloco else opcional. Este é executado quando o ciclo termina sem atingir um break. O uso mais comum é um ciclo de pesquisa que precisa de um valor de substituição caso nada seja encontrado:
for item in items:
if matches(item):
print("found:", item)
break
else:
print("no match")
Se um break for ativado, o bloco else é ignorado. Leia a construção como «for X in Y: …; caso contrário, se nunca saímos com break, faz Z.»
2.13.4. Padrões comuns de ciclos¶
Alguns padrões aparecem frequentemente em scripts reais:
Polling – aguardar que uma condição se torne verdadeira antes de continuar. O corpo utiliza
pass, a instrução de não-operação do Python; cada bloco com recuo deve conter pelo menos uma instrução, epassé a forma de dizer «não fazer nada aqui»:while not ready(): pass proceed()
Máquina de estados – um único ciclo
while True:que decide o que fazer com base numa variável de estado. Útil quando o trabalho se divide claramente em algumas fases com nome: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 se percorre uma sequência:
total = 0 for x in samples: total += x mean = total / len(samples)
Muitos ciclos de acumulação têm um equivalente de uma linha usando uma função incorporada. Recorra à função incorporada quando uma se aplica:
sum()– soma todos os itens de um iterável.any()–Truese pelo menos um item for verdadeiro.all()–Trueapenas quando todos os itens são verdadeiros.sorted()– uma nova lista com os itens ordenados.len()– o número de itens (quando o iterável conhece o 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 com função incorporada é mais curta, mais clara e geralmente mais rápida do que escrever o mesmo ciclo manualmente.