Artigo original: https://www.freecodecamp.org/news/python-while-loop-tutorial/

Boas-vindas! Se você quer aprender como trabalhar com laços em Python, este artigo é para você.

Os laços while são estruturas de programação muito poderosas que você pode usar em seus programas para repetir uma sequência de instruções.

Neste artigo, você aprenderá:

  • O que são os laços while.
  • Para que eles são usados.
  • Quando eles devem ser usados.
  • Como eles funcionam internamente.
  • Como escrever um laço while em Python.
  • O que são laços infinitos e como interrompê-los.
  • Para que usamos while True e sua sintaxe geral.
  • Como usar uma instrução break para interromper um laço while.

Você aprenderá como os laços while funcionam internamente com exemplos, tabelas e diagramas.

Estão prontos? Vamos começar. 🔅

🔹 Finalidade e casos de uso para o laço while

Vamos começar com a finalidade dos laços while. Para que eles são usados?

Eles são usados para repetir uma sequência de instruções um número desconhecido de vezes. Este tipo de laço roda enquanto (while, em inglês) uma dada condição é True (verdadeira) e somente é interrompida quando a condição se torna False (falsa).

Quando escrevemos um laço while, não definimos explicitamente quantas iterações serão realizadas. Somente escrevemos a condição que tem de ser verdadeira (True) para continuar o processo e falsa (False) para interrompê-la.

💡 Dica: se a condição do laço while nunca chegar a ser False, teremos um laço infinito, que é um laço que nunca é interrompido (em tese) sem intervenção externa.

Aqui estão alguns exemplos de casos de uso reais de laços while:

  • Entrada do usuário: quando é solicitado ao usuário que insira algum dado, devemos verificar se o valor inserido é válido. Não podemos saber com antecedência quantas vezes o usuário vai inserir uma entrada inválida antes de o programa poder continuar. Assim, um laço while seria perfeito para esse cenário.
  • Pesquisa: pesquisar por um elemento em uma estrutura de dados é outro caso de uso perfeito para um laço while, pois não podemos saber com antecedência quantas iterações serão necessárias para encontrar o valor procurado. Por exemplo, o algoritmo de Busca binária pode ser implementado usando um laço while.
  • Jogos: em um jogo, um laço while pode ser usado para manter a lógica principal do jogo em execução até que o jogador perca ou que o jogo termine. Não podemos saber antecipadamente quando isso acontecerá, o que torna esse outro cenário perfeito para um laço while.

🔸 Como funcionam os laços while

Agora que você conhece a finalidade dos laços while, vamos ver sua lógica principal e como eles funcionam internamente. Aqui temos um diagrama:

image-24
Laço while

Vamos dividir as peças do diagrama em detalhes:

  • O processo inicia (Start) quando um laço while é encontrado durante a execução do programa.
  • A condição é avaliada (Evaluate Condition) para ver se ela é verdadeira (True) ou false (False).
  • Se a condição for True, as instruções (Statements) que pertencem ao laço serão executadas.
  • A condição do laço while é verificada novamente.
  • Se a condição for True novamente, a sequência de instruções é executada novamente e o processo se repete.
  • Quando a condição for False, o laço é interrompido (Loop Stops -> End) e o programa continua para além do laço.

Uma das características mais importantes dos laços while é o fato de que as variáveis a serem usadas na condição do laço não são atualizadas automaticamente. Precisamos atualizar seus valores explicitamente com nosso código para garantir que o laço, em algum momento, será interrompido quando a condição for avaliada como False.

🔹 Sintaxe geral dos laços while

Ótimo. Agora que você sabe como funcionam os laços while, vamos examinar o código e ver como é possível escrever um laço while em Python. Esta é a sintaxe básica:

image-105
Laço while - nos quadros em azul: Keyword (palavra-chave), Stop if this condition is False (parar se essa condição for falsa), Code that will be repeated (código que será repetido)

Estes são os elementos principais (em ordem):

  • A palavra-chave while (seguida por um espaço).
  • Uma condição (condition, no diagrama) para determinar se o laço continuará em execução ou não com base em seu valor booleano (True ou False ).
  • Dois pontos (:) ao final da primeira linha.
  • A sequência de instruções (code, no diagrama) que será repetida. Este bloco de código é chamado de "corpo" do laço e precisa ser indentado. Se uma instrução não for indentada (ou seja, se não tiver espaços que a precedem, ela não será considerada como parte do laço (veja o diagrama abaixo).
image-7
Parte em azul no diagrama: Indentation (Indentação, em inglês)

💡 Dica: O guia de estilo do Python (PEP 8 - texto em inglês) recomenda o uso de 4 espaços por nível de indentação. A tabulação (uso da tecla Tab) somente deve ser usada para permanecer consistente com o código que já estiver indentado com tabulações.

🔸 Exemplos de laços while

Agora que você sabe como os laços while funcionam e como escrevê-los em Python, vamos ver como eles funcionam internamente com alguns exemplos.

Como um laço while básico funciona

Aqui temos um laço while básico que imprime o valor de i enquanto (while, em inglês) i for inferior a 8 (i < 8):

i = 4

while i < 8:
    print(i)
    i += 1

Se executarmos o código, veremos este resultado:

4
5
6
7

Vamos ver o que acontece internamente quando o código é executado:

image-16
  • Iteração 1: inicialmente, o valor de i é 4, então a condição i < 8 é avaliada como True e o laço começa a ser executado. O valor de i é impresso (4) e esse valor é incrementado em 1. O laço recomeça.
  • Iteração 2: agora o valor de i é 5, então a condição i < 8 segue sendo avaliada como True. O corpo do laço é executado, o valor de i é impresso (5) e esse valor i é incrementado em 1. O laço recomeça.
  • Iterações 3 e 4: o mesmo processo é repetido para a terceira e a quarta iterações, então os números inteiros 6 e 7 são impressos.
  • Antes de começar a quinta iteração, o valor de i é 8. Agora, a condição do laço while, i < 8, é avaliada como False e o laço é interrompido imediatamente.

💡 Dica: se a condição do laço while for False antes de iniciar a primeira iteração, o laço while sequer começará a ser executado.

Entrada do usuário com um laço while

Agora, vamos ver um exemplo de laço while em um programa que recebe entradas do usuário. Usaremos a função input() para pedir ao usuário que insira um número inteiro, que somente será adicionado a uma lista se for par.

Este é o código:

# Define a lista
nums = []

# O laço será executado enquanto o tamanho da
# lista nums for menor que 4
while len(nums) < 4:
    # Pede ao usuário uma entrada e a armazena em uma variável como número inteiro.
    user_input = int(input("Insira um número inteiro: "))
    # Se a entrada for um número par, é adicionada à lista
    if user_input % 2 == 0:
        nums.append(user_input)

A condição do laço é len(nums) < 4. Assim, o laço será executado enquanto o tamanho da lista nums for estritamente inferior a 4.

Vamos analisar esse programa linha por linha:

  • Começamos definindo uma lista vazia e atribuindo a ela uma variável chamada nums.
nums = []
  • Em seguida, definimos um laço while que será executado enquanto len(nums) < 4.
while len(nums) < 4:
  • Pedimos pela entrada do usuário com a função input() e armazenamos essa entrada na variável user_input.
user_input = int(input("Insira um número inteiro: "))

💡 Dica: Precisamos converter (fazer o casting) do valor inserido pelo usuário para um número inteiro usando a função int() antes de atribui-la à variável, pois a função input() retorna uma string (fonte).

  • Verificamos se esse valor é par ou ímpar.
if user_input % 2 == 0:
  • Se for par, inserimos esse valor na lista nums.
nums.append(user_input)
  • Do contrário, se for ímpar, o laço recomeça e a condição é verificada para determinar se o laço deve ou não continuar a ser executado.

Se executarmos esse código com entradas de usuário personalizadas, temos o seguinte resultado:

Insira um número inteiro: 3
Insira um número inteiro: 4    
Insira um número inteiro: 2    
Insira um número inteiro: 1
Insira um número inteiro: 7
Insira um número inteiro: 6    
Insira um número inteiro: 3
Insira um número inteiro: 4    

A tabela abaixo resume o que acontece internamente quando o código é executado:

image-86

💡 Dica: o valor inicial de len(nums) é 0, pois a lista está vazia inicialmente. A última coluna da tabela mostra o tamanho da lista ao final da iteração atual. Esse valor é usado para verificar a condição antes de a próxima interação começar.

Como é possível ver na tabela, o usuário insere números inteiros na segunda, terceira, sexta e oitava iterações e esses valores são inseridos na lista nums.

Antes de uma "nona" iteração começar, a condição é verificada novamente. Agora, no entanto, ela é avaliada como False, pois a lista nums tem quatro elementos (tamanho - length, em inglês - igual a 4). O laço é, então, interrompido.

Se verificarmos o valor da lista nums quando o processamento estiver concluído, teremos:

>>> nums
[4, 2, 6, 4]

É exatamente o que esperávamos. O laço while parou quando a condição len(nums) < 4 foi avaliada como False.

Agora, você sabe como o laço while funciona internamente e viu alguns exemplos práticos. Vamos passar, então, para um elemento chave dos laços while: a condição.

🔹 Dicas para a condição nos laços while

Antes de começar a trabalhar com os laços while, você precisa saber que a condição do laço tem um papel fundamental na funcionalidade e no resultado de um laço while.

image-25

É preciso muito cuidado com o operador de comparações que você seleciona. Ele é uma fonte muito comum de erros.

Erros comuns incluem, por exemplo:

  • Usar < (menor que) em vez de <= (menor que ou igual a), ou ao contrário.
  • Usar > (maior que) em vez de >= (maior que ou igual a), ou ao contrário.

Isso pode afetar o número de iterações do laço e até seu resultado.

Vejamos um exemplo:

Se escrevermos esse laço while com a condição i < 9:

i = 6

while i < 9:
    print(i)
    i += 1

Teremos este resultado quando o código é executado:

6
7
8

O laço completa três iterações e para quando i é igual a 9.

Esta tabela ilustra o que acontece internamente quando o código é executado:

image-20
  • Antes da primeira iteração do laço, o valor de i é 6. Assim, a condição i < 9 é True e o laço começa a ser executado. O valor de i é impresso e seu valor é aumentado em 1.
  • Na segunda iteração do laço, o valor de i é 7. Assim, a condição i < 9 é True. O corpo do laço é executado, o valor de i é impresso e seu valor é aumentado em 1.
  • Na terceira iteração do laço, o valor de i é 8. Assim, a condição i < 9 é True. O corpo do laço é executado, o valor de i é impresso e seu valor é aumentado em 1.
  • A condição é verificada novamente antes de uma quarta iteração ser iniciada, mas agora o valor de i é 9. Assim, i < 9 é False e o laço é interrompido.

Neste caso, usamos < como o operador para comparações na condição. O que aconteceria, porém, se usássemos <= em seu lugar?

i = 6

while i <= 9:
    print(i)
    i += 1

Teríamos este resultado:

6
7
8
9

O laço teria uma iteração a mais, pois agora estaríamos usando o operador "menor que ou igual a" <= . Desse modo, a condição ainda seria True quando i fosse igual a 9.

Esta tabela ilustra o que acontece internamente:

image-21

Quatro iterações são concluídas. A condição é verificada novamente antes de começar uma "quinta" iteração. Nesse momento, o valor de i é 10. Assim, a condição i <= 9 é False e o laço é interrompido.

🔸 Laços while infinitos

Agora, você sabe como funcionam os laços while. O que aconteceria, porém, se a condição do laço while jamais fosse avaliada como False?

image-109

O que são os laços while infinitos?

Lembre-se de que os laços while não atualizam as variáveis automaticamente (é nossa responsabilidade fazer isso explicitamente no código). Desse modo, não há garantias de que o laço será interrompido a menos que nós passemos a ele o código necessário para tornar a condição False em algum momento da execução do laço.

Se não fizermos isso e se a condição for sempre avaliada como True, teremos um laço infinito, que é o que ocorre quando um laço while é executado indefinidamente (em teoria).

Laços infinitos são, tipicamente, o resultado de um bug, mas também podem ser causados intencionalmente, se quisermos repetir uma sequência de instruções indefinidamente até que uma instrução break seja encontrada.

Vamos ver dois tipos de laços infinitos nos exemplos abaixo.

💡 Dica: bugs são erros no programa que causam resultados incorretos ou inesperados.

Exemplo de laço infinito

Este é um exemplo de um laço infinito não intencional causado por um erro no programa:

# Define uma variável
i = 5

# Executa este laço enquanto i for menor que 15
while i < 15:
    # Imprime uma mensagem
    print("Olá, mundo!")
    

Analise esse código por um instante.

Percebe que falta algo no corpo do laço?

É isso!

O valor da variável i nunca é atualizado (ele sempre será 5). Portanto, a condição i < 15 é sempre True e o laço nunca é interrompido.

Se rodarmos esse código, o resultado será uma sequência "infinita" de mensagens Olá, mundo!, pois o corpo do laço print("Olá, mundo!") será executado indefinidamente.

Olá, mundo!
Olá, mundo!
Olá, mundo!
Olá, mundo!
Olá, mundo!
Olá, mundo!
Olá, mundo!
Olá, mundo!
Olá, mundo!
Olá, mundo!
Olá, mundo!
Olá, mundo!
Olá, mundo!
Olá, mundo!
Olá, mundo!
Olá, mundo!
Olá, mundo!
Olá, mundo!
.
.
.
# Continua indefinidamente

Para interromper o programa, precisaremos parar o laço manualmente pressionando CTRL + C.

Quando fizermos isso, veremos um erro do tipo KeyboardInterrupt, semelhante ao que vemos abaixo:

image-116

Para consertar esse laço, precisamos atualizar o valor de i no corpo do laço para garantir que a condição i < 15, em algum momento, seja avaliada como False.

Essa é uma solução possível: aumentar o valor de i de 2 em 2 a cada iteração:

i = 5

while i < 15:
    print("Olá, mundo!")
    # Atualiza o valor de i
    i += 2

Muito bem. Agora, sabemos como consertar laços infinitos causados por um erro. É preciso apenas escrever o código necessário para garantir que a condição seja avaliada como False em algum momento da execução.

Vamos ver agora laços infinitos intencionais e como eles funcionam.

🔹 Como criar um laço infinito com while True

Podemos gerar um laço infinito intencionalmente com while True. Neste caso, o laço será executado indefinidamente até que o processo seja interrompido por uma intervenção externa (CTRL + C) ou quando uma instrução break for encontrada (você saberá mais sobre a instrução break em instantes).

Esta é a sintaxe básica:

image-35
Laço while - na caixa em azul: Write the truth value directly (use o valor 'True' diretamente)

Em vez de escrever uma condição após a palavra-chave while, simplesmente escrevemos o valor de verdade ("True") diretamente para indicar que a condição sempre será True.

Aqui temos um exemplo:

>>> while True:
	print(0)

	
0
0
0
0
0
0
0
0
0
0
0
0
0
Traceback (most recent call last):
  File "<pyshell#2>", line 2, in <module>
    print(0)
KeyboardInterrupt

O laço é executado até que CTRL + C é pressionado, mas o Python também tem uma instrução break que podemos usar diretamente em nosso código para interromper esse tipo de laço.

A instrução break

Essa instrução é usada para interromper um laço imediatamente. Pense nela como um "sinal de Pare" vermelho que você pode usar no seu código para ter mais controle sobre o comportamento do laço.

image-110
break é igual a um sinal de Pare (Stop, em inglês)

De acordo com a documentação do Python:

O comando break, como no C, sai imediatamente do laço de repetição mais interno, seja for ou while.

Este diagrama ilustra a lógica básica da instrução break:

image-111
A instrução break: Start (Iniciar), Check Condition (Verificar condição), break? (Interromper?), Continue Body (Seguir com o corpo do laço), Exit Loop (Sair do laço), End (Encerrar) - False, True, Yes (Falso, Verdadeiro e Sim, respectivamente)

Esta é a lógica básica da instrução break:

  • O laço while inicia somente se a condição for avaliada como True.
  • Se uma instrução break for encontrada em algum ponto durante a execução do laço, o laço é interrompido imediatamente.
  • Do contrário, se break não for encontrado, o laço continua em seu curso normal e é interrompido apenas quando a condição for avaliada como False.

Podemos usar break para interromper um laço while quando uma condição for atendida em um momento específico da execução. Assim, você encontrará a instrução, tipicamente, dentro de uma instrução condicional, assim:

while True:
    # Código
    if <condição>:
    	break
    # Código

Isso interrompe o laço imediatamente se a condição for True.

💡 Dica: é possível (em tese) escrever uma instrução break em qualquer ponto do corpo do laço. Não necessariamente ela precisa ser parte de um condicional, mas usamos esse recurso com frequência para interromper o laço quando uma determinada condição for True.

Aqui temos um exemplo de break em um laço while True:

image-41
Linhas que aparecem na tela para o usuário, em amarelo: "Enter an integer: " ("Insira um número inteiro: "), "This number is odd" (Este número é ímpar), "This number is even" (Este número é par)

Vejamos o código em detalhes:

A primeira linha define um laço while True que será executado indefinidamente até que uma instrução break seja encontrada (ou até que ele seja interrompido com CTRL + C).

while True:

A segunda linha pede uma entrada ao usuário. Essa entrada é convertida em um número inteiro e atribuída à variável user_input.

user_input = int(input("Insira um número inteiro: "))

A terceira linha verifica se a entrada era ímpar.

if user_input % 2 != 0:

Se for, a mensagem Este número é ímpar é impressa na tela e a instrução break interrompe o laço imediatamente.

print("Este número é ímpar")
break

Do contrário, se o número for par, a mensagem Este número é par é impressa e o laço é iniciado novamente.

print("Este número é par")

O laço será executado indefinidamente até que um número ímpar seja inserido, pois essa é a única maneira de encontrarmos a instrução break.

Aqui, temos um exemplo com entradas personalizadas de usuário:

Insira um número inteiro: 4
Este número é par
Insira um número inteiro: 6
Este número é par
Insira um número inteiro: 8
Este número é par
Insira um número inteiro: 3
Este número é ímpar
>>> 

🔸 Em resumo

  • Os laços while são estruturas de programação usadas para repetir uma sequência de instruções enquanto uma condição for True (verdadeira). Eles são interrompidos quando a condição for avaliada como False (falsa).
  • Quando você escreve um laço while, precisa fazer as atualizações necessárias em seu código para garantir que o laço será interrompido em algum momento.
  • Um laço infinito é um laço que é executado indefinidamente e que somente é interrompido por uma intervenção externa ou quando uma instrução break é encontrada.
  • Você pode interromper um laço infinito com CTRL + C.
  • Você pode gerar um laço infinito intencionalmente com while True.
  • A instrução break pode ser usada para interromper um laço while imediatamente.

Espero, sinceramente, que você tenha gostado do artigo e que tenha achado que ele foi útil. Agora, você sabe como funcionam os laços while em Python.

Siga a autora no Twitter @EstefaniaCassN e, se quiser aprender mais sobre esse tópico, confira o curso on-line da autora: Python Loops and Looping Techniques: Beginner to Advanced (em inglês).