Como Usar os Laços de Repetição for e while em Python? (Com Exercícios)

Os laços de repetição são estruturas de controle do programa usadas para repetir a execução de um bloco de código enquanto uma condição for verdadeira. Cada repetição desse bloco de código é chamada de iteração. Em Python há dois tipos de laços de repetição: o laço determinado for, usado para realizar um número fixo de iterações, e o laço indeterminado while, usado quando não se sabe quantas iterações serão necessárias antes do início do laço. Para o laço for se repetir, é necessário que a coleção iterada contenha mais itens. Já para o laço while, a condição lógica é verificada antes de cada iteração e o laço só continua se essa condição for avaliada como True.

Veja nesse post como escrever e quando usar cada um dos laços de repetição existentes na linguagem Python.

Eu sugiro que você execute o código Python mostrado nesse post no Jupyter Lab para treinar.

O Jupyter Lab é uma ferramenta ótima para começar a programar e deve fazer parte da sua lista de ferramentas como programador.

Se você ainda não tem o Jupyter Lab instalado, dá uma olhada nesse post onde eu explico o passo-a-passo para a instalação.

Qual é a sintaxe dos laços de repetição for e while em Python?

Como fazer um laço for em Python

for <variável> in <coleção iterável>: # Bloco de código que deve se repetir

Para entender melhor como esse laço funciona, veja alguns exemplos abaixo.

# Exemplo 1 for letra in ['a', 'b', 'c', 'd']: # Iterando sobre uma lista print(letra) # Exemplo 2 for letra in 'texto': # Iterando sobre uma string print(letra) # Exemplo 3 – Cálculo de Fatorial # Multiplicar um número n por todos os números de 1 a (n-1) n = int(input('Digite um número:')) fatorial = 1 for x in range(n): # range() produz n números, de 0 a n-1 fatorial *= x + 1 print(fatorial)

Antes de explicar essa sintaxe em detalhes, é importante falar sobre a maneira como esse tipo de laço funciona em Python, que é diferente de como ele funciona em outras linguagens.

Na maioria das linguagens de programação baseadas em C, o laço for é executado sobre uma sequência de números inteiros.

A variável declarada no laço funciona como um contador que indica o número da iteração que está sendo executada.

Além disso, o for também inclui a condição lógica para que o laço termine e o incremento da variável.

Em Java, por exemplo, o laço for é escrito dessa forma:

for(int i = 0; i < 5; i++) { # Itera 5 vezes, com o contador “i” indo de 0 a 4 }

A forma de controlar o laço for é diferente em Python.

Em Python, o laço for é executado sobre uma coleção de objetos.

Isso significa que é possível iterar sobre diversos tipos de objetos e não apenas sobre números inteiros, como você viu nos exemplos no início dessa seção.

A única restrição é que essa coleção de objetos precisa ser iterável.

E o que isso significa?

Um iterável (iterable) é um tipo de objeto que, quando passado para a função embutida iter(), retorna um iterator.

Parece complicado, ainda mais com todos esses nomes tão parecidos, mas é bem simples.

Um iterator é objeto que representa um fluxo de dados. Ele é o responsável por dividir o iterável e retornar cada um dos seus elementos.

Nos exemplos acima, você viu o laço for sendo executado sobre uma lista (1), uma string (2) e uma sequência obtida a partir da função range() (3).

Esses três tipos de objetos são iteráveis, assim como tuplas, dicionários e conjuntos.

Na prática, quase todos os tipos de objetos em Python são iteráveis.

Isso quer dizer que você pode passar qualquer objeto desses tipos para um laço for e iterar sobre os seus elementos.

Agora que você já entendeu como funcionam os objetos iteráveis, fica mais fácil entender a sintaxe do laço for.

Veja mais um exemplo:

lista = [1, 2, 3] for x in lista: x += 1 print(x) print(lista)

O laço for sempre obtém o próximo elemento da coleção iterável e guarda seu valor na variável. Nesse exemplo, a variável é x.

No início do laço, o próximo valor é o primeiro, caso a coleção não esteja vazia.

O bloco de código é executado até o fim e o controle retorna à linha do for para que uma nova iteração aconteça, com o próximo elemento da coleção.

Lembre-se que um bloco de código em Python é definido pela indentação.

O processo então se repete até que a coleção se esgote e não haja mais um próximo elemento. Quando isso acontece, o controle passa para a primeira instrução fora do laço e a execução do programa segue linha a linha.

O valor da variável que recebe o item da coleção pode ser acessado e até alterado no bloco de código. No exemplo acima, isso ocorre na linha x += 1.

No entanto, essa variável contém apenas uma cópia do valor do item. Qualquer alteração nesse valor não é refletida na coleção original.

Se você executar o exemplo acima, vai ver que os elementos da lista não mudam depois do for, mesmo com a variável x sendo incrementada a cada iteração do laço.

E se você quiser usar um comportamento semelhante ao das linguagens baseadas em C, onde o for tem um contador numérico simples?

É fácil. Basta usar a função range(). Ela produz uma sequência de números com início e fim determinados.

Se você só informar um número como argumento para a função range() ele será usado como fim do intervalo, porque o default é a sequência começar em 0.

for x in range(n): # Esse bloco executa n vezes e x recebe os valores de 0 a n-1 # Exemplo com 1 parâmetro for x in range(5): # Esse bloco executa 5 vezes e x recebe os valores de 0 a 4 print(x) # O código acima equivale a escrever for x in [0, 1, 2, 3, 4]: # Esse bloco executa 5 vezes e x recebe os valores de 0 a 4 print(x) # Exemplo com 2 parâmetros for x in range(1, 5): # Esse bloco executa 4 vezes e x recebe os valores de 1 a 4 print(x) # O código acima equivale a escrever for x in [1, 2, 3, 4]: # Esse bloco executa 4 vezes e x recebe os valores de 1 a 4 print(x)

Também é possível passar para o for uma referência à função range() definida antes do laço:

seq = range(5) for x in seq: # Esse bloco executa 5 vezes e x recebe os valores de 0 a 4 print(x)

E se você estiver usando um objeto iterável que não seja uma sequência numérica, mas precisar de um contador dentro do laço for?

Basta criar um contador externo incrementado a cada iteração, não é? Alguma coisa assim:

i = 0 for letra in 'Um texto qualquer': print(i, letra) i += 1 # Incrementa o contador

Na verdade, isso não é necessário.

Em Python há um jeito mais fácil de fazer isso usando a função embutida enumerate(). Essa função retorna uma tupla com dois valores: o primeiro é o contador (iniciando em 0) e o segundo é o elemento original do objeto iterável.

for i, letra in enumerate('Um texto qualquer'): print(i, letra)

Muito mais fácil, não é?

Agora que você já sabe como o laço for funciona, veja a seguir a sintaxe do laço while.

Como fazer um laço while em Python

while <condição lógica>: # Bloco de código

Veja esses exemplos de código para entender melhor como usar o laço while:

# Exemplo 1 sair = False while not sair: comando = input('Digite um comando:') print(comando) if comando == 'sair': sair = True print('Saiu do laço.') # Exemplo 2 – Imprimindo números aleatórios from numpy.random import randn n = randn() while n > -1: print(n) n = randn() print(n) # Exemplo 3 – Exemplo 2 com laço infinito from numpy.random import randn while True: # A condição é sempre verdadeira n = randn() print(n) if n <= -1: break

A condição lógica do laço while funciona da mesma forma que na declaração if. Ou seja, essa condição pode ser escrita usando operadores relacionais e lógicos e deve sempre retornar um valor booleano.

Observe que você deve escrever algum código antes do laço while, para garantir que a condição será avaliada sem erros, ainda que retorne False já da primeira vez.

Por exemplo, as variáveis contidas na condição devem ser declaradas antes de serem usadas.

Para evitar de ter que fazer isso, você pode usar um laço infinito while True: e interromper a execução quando uma condição ocorrer, como no exemplo 3. Veja os detalhes sobre como fazer isso mais adiante nesse post.

Para que serve o else em um laço for ou while?

Os laços for e while em Python aceitam o uso de uma cláusula else. O bloco de códido do else é executado quando a condição do laço retornar False e as iterações terminarem.

>>> for i in range(2): ... print(i) ... else: ... print('Fim') ... 0 1 Fim >>> for i in range(2): ... break ... else: ... print('Fim') ... >>>

No primeiro exemplo acima, a instrução print('Fim') é executada assim que os valores retornados pela função range(2) se esgotam.

Já no segundo exemplo, o else não é executado, porque o laço é interrompido com break, fazendo com que a condição pare de ser avaliada. Ou seja, o laço nunca retorna False.

Agora que você já sabe como escrever os laços de repetição e já entendeu como eles funcionam, veja quando usar cada um deles.

Qual é a diferença de usar for e while?

Para saber se você deve usar o laço for ou o laço while, basta avaliar se o número de repetições é conhecido no início do laço.

Se você souber quantas vezes precisa repetir o bloco de código, use o for. Senão, use o while e manipule as variáveis da condição dentro do bloco.

Como você viu na definição lá no início do post, tanto no laço for quanto no while, a execução do bloco de código é repetida até que a coleção esteja esgotada ou até que a condição lógica não seja mais verdadeira.

Mas apesar de parecer que ambos os laços fazem a mesma coisa, usando a regra acima é muito fácil saber quando usar cada um.

Por exemplo, imagine duas situações nas quais você esteja pensando em poupar dinheiro.

Na primeira, você sabe quanto dinheiro quer poupar no total e quanto dinheiro vai poupar por mês, mas não sabe quantos meses vai levar até chegar nesse valor.

Essa situação poderia ser escrita como um laço while.

montante = .0 # Valor do saldo corrente objetivo = 10_000 capital = 300 # Valor aplicado a cada mês txJuros = .3 / 100 # rendimento de 0,3% ao mês meses = 0 while montante < objetivo: montante += capital # Aplicação no início do período juro = montante * txJuros # Juros compostos montante += juro meses += 1 print(f'Montante no mês {meses} = R${montante:.2f}') print(f'Número de meses: {meses}')

Dessa forma, com esse valor aplicado a essa taxa de juros, você conseguiria calcular que seriam necessários 32 meses para alcançar o seu objetivo.

Na segunda situação você não tem um montante final em mente, mas se compromete a poupar o mesmo valor durante os próximos 12 meses. Esse seria um caso de uso do laço for.

montante = .0 # Valor do saldo corrente capital = 300 # Valor aplicado em cada período txJuros = .3 / 100 # rendimento de 0,3% ao mês meses = 12 for mes in range(meses): montante += capital juro = montante * txJuros # Juros compostos montante += juro print(f'Montante no mês {mes + 1} = R${montante:.2f}')

Nesse cenário, você conseguiria calcular que o valor poupado ao longo de 12 meses seria de R$3670,98.

!

Cuidado com as famosas “gambiarras”.

Você pode se deparar com algum código onde um laço for é usado com uma sequência numérica enorme e depois terminado à força no meio, para imitar o comportamento de um laço while.

Ou você pode encontrar um código onde só há laços while e todos tem um contador interno que interrompe as iterações depois de n execuções.

É provável que quem escreveu esse código não sabia o que estava fazendo ou não conhecia muito bem a linguagem Python.

Além de tornar o código menos legível, isso adiciona complexidade desnecessária e pode criar bugs difíceis de identificar.

Portanto, não repita esse tipo de coisa. Use a estrutura correta para cada situação.

Por ser um laço indeterminado, é comum usar laço while para qualquer situação na qual o processamento deve se repetir, mas as entradas são aleatórias.

Isso é o que acontece nas interfaces de usuário.

Como você sabe, a execução de um programa ocorre de maneira sequencial, linha a linha e termina de forma normal quando a última instrução é executada.

Mas, se o que você quer é continuar processando diversas vezes a entrada do usuário, basta usar um laço while.

Veja como aplicar essa ideia ao exemplo do cálculo do fatorial que você viu no início do post.

while True: n = int(input('Digite um número:')) fatorial = 1 for x in range(n): # Função que produz n números, de 0 a n-1. fatorial *= x + 1 print(fatorial)

Veja que não é preciso inicializar variáveis para a condição lógica, já que esse é um laço infinito. Não é surpresa alguma que a avaliação de True sempre retorna… True!

E como fazer para interromper a execução desse laço, quando não houver mais cálculos a fazer?

Isso é o que você vai ver na próxima seção.

Como interromper os laços de repetição for e while?

Nos exemplos que você viu até agora, os laços for e while executaram as linhas do bloco de código até o fim.

No entanto, em algumas situações você precisa interromper a execução do bloco dentro do laço.

Para isso há duas declarações específicas em Python: break e continue.

Ao encontrar a declaração break, o programa interrompe a execução do bloco de código e o controle passa para a primeira linha após o laço.

No exemplo de cálculo do fatorial da seção anterior, o programa fica o tempo inteiro aguardando uma entrada do usuário para calcular o fatorial. Não há como sair desse laço infinito.

Agora veja uma nova versão desse exemplo, usando a declaração break para finalizar o laço caso o usuário não digite um valor e pressione Enter.

while True: entrada = input('Digite um número:') if not entrada: print('Fim.') break n = int(entrada) fatorial = 1 for x in range(n): # Função que produz n números, de 0 a n-1. fatorial *= x + 1 print(fatorial)

Assim como a declaração break, o continue interrompe a execução do laço. A diferença é que com o continue, a execução do programa retorna para o início do laço.

Veja uma outra versão do exemplo acima, usando a declaração continue para impedir o cálculo do fatorial sem interromper o programa caso o usuário digite um valor negativo.

while True: entrada = input('Digite um número:') if not entrada: print('Fim do laço.') break n = int(entrada) if n < 0: print('Não é possível calcular o fatorial de um número negativo.') continue fatorial = 1 for x in range(n): # Função que produz n números, de 0 a n-1. fatorial *= x + 1 print(fatorial)

As declarações break e continue podem ser usadas para interromper laços while e for da mesma maneira.

Existe uma terceira forma de interromper um laço de repetição em Python. Ela não está relacionada à sintaxe do laço, mas sim à maneira como as funções funcionam nas linguagens de programação.

Se o laço estiver dentro de uma função, a declaração return provoca o término da função sem executar as demais instruções.

Veja como ficaria o exemplo acima usando return.

def fatorial(): # Declaração da função while True: entrada = input('Digite um número:') if not entrada: print('Fim do laço.') return # Termina a função n = int(entrada) if n < 0: print('Não é possível calcular o fatorial de um número negativo.') continue fatorial = 1 for x in range(n): fatorial *= x + 1 print(fatorial) return # Nunca vai passar aqui fatorial() print('Fim do programa.')

Mas atenção:

Em um programa real, o controle da interface de usuário e a lógica de cálculo do fatorial não estariam amontoados na mesma função.

Além disso, eu considero uma prática ruim uma função complexa ter vários pontos de saída (return), ainda mais se um deles for no meio de um laço.

Retornar de uma função no meio de um laço vai tornar seu código confuso e difícil de ler.

Portanto, o exemplo acima só serve para você saber que essa forma de interrupção existe e que você não deve programar desse jeito.

Se você reparou, nesse exemplo eu usei um laço for dentro de um laço while.

Essa é uma construção bastante comum e você vai aprender mais sobre ela na seção a seguir.

Como usar laços de repetição for e while aninhados?

É comum encontrar laços de repetição dentro de outros laços.

Isso acontece, por exemplo, quando você precisa iterar sobre uma matriz bidimensional. O laço de fora itera pelas linhas e o de dentro por cada valor de uma linha, ou seja, as colunas.

Veja a seguir um exemplo de cálculo de todas as tabuadas de 1 a 9. A função format() é usada somente para apresentar todos os valores com 2 dígitos.

for linha in range(1, 10): # Linhas de 1 a 9 for coluna in range(1, 11): # Colunas de 1 a 10 print('{:2}'.format(linha * coluna), end = ' ') # end = ' ' evita a quebra de linha print('') # Quebra a linha

Apenas como uma curiosidade, em Python é possível usar a função itertools.product() para fazer o produto das duas sequências e iterar sobre o resultado em um laço só, mas ainda tendo acesso a cada valor individual.

import itertools for linha,coluna in itertools.product(range(1, 10), range(1, 11)): print('{:2}'.format(linha * coluna), end = ' ') if coluna == 10: print('')

É claro que esse é um exemplo avançado e eu não espero que você escreva esse tipo de código agora. O objetivo é só mostrar como tudo pode ser simplificado na linguagem Python.

Apesar de menos comuns, os laços while dentro de outros laços while também são permitidos, assim como laços for dentro de while e vice-versa.

No entanto, eu recomendo que você tome cuidado com isso e evite usar mais do que dois níveis de laços aninhados, ou a complexidade do seu código vai aumentar demais.

Exercícios resolvidos sobre laços de repetição for e while em Python

A melhor maneira de aprender a programar é…

Programando!

Por isso, eu elaborei alguns exercícios para você praticar o uso dos laços de repetição for e while em Python:

1. Leia n números digitados pelo usuário e calcule o produto desses números.

2. Altere o programa do exercício anterior para proibir a multiplicação por 0.

3. Imprima a tabela verdade da relação lógica XOR, com os cabeçalhos, no formato abaixo.

a |b |Resultado False |False |? False |True |? True |False |? True |True |?

4. Imprima a lista dos 100 menores quadrados perfeitos ímpares maiores do que 1, separados por vírgula.

5. Leia 4 números inteiros e imprima se eles foram digitados em ordem crescente, decrescente ou fora de ordem. Teste com as sequências:

  • 1 2 3 4
  • 4 3 2 1
  • 1 2 1 2
  • 2 1 2 1

Para você poder conferir as suas respostas, eu preparei um notebook no Jupyter Lab com as soluções de todos os exercícios comentadas. Baixe agora e veja como você se saiu!

Respostas comentadas dos exercícios sobre laços for e while

Baixe grátis as soluções comentadas dos exercícios e confira suas respostas.

Não enviamos spam. Cancele a qualquer momento.

Ainda não instalou o Jupyter Lab? Dá uma olhada nesse post onde eu detalho todos os passos da instalação de forma muito fácil.

Conclusão

Nesse post você viu que os laços de repetição for e while são usados para iterar sobre blocos de código, com base em uma coleção iterável ou enquanto uma condição for verdadeira.

Além disso, entendeu quando usar cada um deles e como alterar o fluxo normal de execução de um laço.

Agora que você já sabe usar os laços for e while, não perca a chance de fazer os exercícios e conferir as soluções com explicações detalhadas.

O que você achou? Comente aqui embaixo! Compartilhe também outras maneiras de responder os exercícios. E não esqueça de dizer como eu posso melhorar esse post!

Guilherme Brügger D Amato - Audiência Pública na Comissão Senado do Futuro

Guilherme Brügger D’Amato é servidor concursado de TI na Câmara dos Deputados, onde ocupou o cargo de Diretor de Informática entre 2015 e 2016. Com mais de 25 anos de experiência como programador e executivo de TI, já desenvolveu sites e sistemas usados por dezenas de milhões de pessoas. Conecte-se com ele no LinkedIn.

Deixe um comentário