1.10. Estruturas de Controle

Como observamos anteriormente, algoritmos exigem duas importantes estruturas de controle: iteração e seleção. Ambas são suportadas pelo Python em várias formas. O programador pode escolher o comando que lhe for mais útil dada uma circunstância.

Para a iteração, o Python fornece um comando padrão while e um comando muito poderoso for. O comando while repete um corpo de código enquanto uma condição for verdadeira. Por exemplo,

>>> contador = 1
>>> while contador <= 5:
...     print("Olá, mundo")
...     contador = contador + 1

Olá, mundo
Olá, mundo
Olá, mundo
Olá, mundo
Olá, mundo

imprime a frase “Olá, mundo” cinco vezes. A condição no comando while é avaliada no início de cada repetição. Se o condição é True (verdadeira), o corpo do comando será executado. É fácil ver a estrutura de um comando while do Python devido ao padrão de tabulação obrigatório imposto pela linguagem.

O comando while é uma estrutura iterativa de propósito geral que usaremos em vários algoritmos diferentes. Em muitos casos, uma condição composta controlará a iteração. Um fragmento como

while contador <= 10 and not acabou:
...

faria com que o corpo da declaração fosse executado apenas no caso onde ambas as partes da condição são satisfeitas. O valor da variável contador precisaria ser menor ou igual a 10 e a variável acabou precisaria ser False (pois not False é True) para que True and True resulte em True.

Mesmo que este tipo de construção seja muito útil em uma ampla variedade de situações, outra estrutura iterativa, o comando for, pode ser usado em conjunto com muitas das coleções do Python. O comando for pode ser usado para iterar sobre os membros de uma coleção, desde que a coleção seja uma sequência. Então, por exemplo,

>>> for item in [1,3,6,2,5]:
...    print(item)
...
1
3
6
2
5

atribui à variável item a cada valor sucessivo na lista [1,3,6,2,5]. O corpo da iteração é então executado. Isso funciona para qualquer coleção que seja uma sequência (listas, tuplas e strings).

Um uso comum do comando for é implementar uma iteração definida em um intervalo de valores. O comando

>>> for item in range(5):
...    print(item**2)
...
0
1
4
9
16
>>>

executará a função print cinco vezes. A função range retornará um objeto de intervalo representando a sequência 0,1,2,3,4 e cada valor será atribuído à variável item. Este valor é então elevado ao quadrado e impresso.

A outra versão muito útil desta estrutura de iteração é usada para processar cada caractere de uma string. O seguinte fragmento de código itera sobre uma lista de strings e para cada string processa cada caractere, anexando-o no final de uma lista. O resultado é uma lista de todas as letras em todas as palavras.

Os comandos de seleção permitem que os programadores façam perguntas e, em seguida, dependendo do resultado, execute ações diferentes. A maioria das linguagens de programação fornecem duas versões desta construção útil: o ifelse (se-senão) e o if (se). Segue um exemplo simples de uma seleção binária usando o comando ifelse.

if n<0:
   print("Desculpe, o valor é negativo")
else:
   print(math.sqrt(n))

Neste exemplo, o objeto referido por n é verificado para ver se é menor que zero. Se for, uma mensagem é impressa informando que é negativo. Se não for, a declaração executa a cláusula else e calcula a raiz quadrada.

Construções de seleção, assim como em qualquer construção de controle, podem ser aninhadas de forma que o resultado de uma pergunta ajuda a decidir o que perguntar em seguida. Por exemplo, suponha que nota seja uma variável contendo uma referência a uma pontuação para um teste de ciência da computação.

if nota >= 90:
   print('A')
else:
   if nota >=80:
      print('B')
   else:
      if nota >= 70:
         print('C')
      else:
         if nota >= 60:
            print('D')
         else:
            print('F')

Este fragmento irá classificar um valor chamado nota imprimindo uma categoria correspondente de A a F. Se a pontuação for maior ou igual a 90, o código irá imprimir A. Senão (else), a próxima pergunta é feita. Se a pontuação for maior ou igual a 80, então a nota deve estar entre 80 e 89, uma vez que a resposta à primeira questão foi falsa. Neste caso, a categoria B é impressa. Você pode ver que o padrão de tabulação do Python ajuda a dar sentido à associação entre if e else sem precisar de elementos sintáticos adicionais.

Uma sintaxe alternativa para esse tipo de seleção aninhada usa o palavra-chave elif. O else e o próximo if são combinados de modo a eliminar a necessidade de níveis adicionais de aninhamento. Note que o else final ainda é necessário para fornecer o caso default se todas as outras condições falharem.

if nota >= 90:
   print('A')
elif nota >=80:
   print('B')
elif nota >= 70:
   print('C')
elif nota >= 60:
   print('D')
else:
   print('F')

O Python também possui uma construção de seleção unária, o comando if. Com esse comando, se a condição for verdadeira, uma ação será executada. No caso da condição ser falsa, o processamento simplesmente continua para a próxima instrução após o if. Por exemplo, o seguinte fragmento irá primeiro verificar se o valor de uma variável n é negativo. Se for, então é modificado pela função de valor absoluto. Independentemente disso, a próxima ação é calcular a raiz quadrada.

if n<0:
    n = abs(n)
print(math.sqrt(n))

Auto avaliação

Teste sua compreensão do que cobrimos até agora resolvendo o seguinte exercício. Modifique o código do Activecode 8 para que a lista final contenha apenas uma única cópia de cada letra.

Voltando às listas, existe um método alternativo para criar uma lista que usa construções de iteração e seleção conhecidas como preenchimento de lista (do inglês list comprehension). Uma construção para preenchimento de lista permite que você crie facilmente uma lista com base em alguns critérios de processamento ou seleção. Por exemplo, se quiséssemos criar uma lista dos primeiros 10 quadrados perfeitos, poderíamos usar um comando for:

>>> quadrados=[]
>>> for x in range(1,11):
         quadrados.append(x*x)

>>> quadrados
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
>>>

Usando preenchimento de lista, podemos fazer isso em um passo apenas

>>> quadrados=[x*x for x in range(1,11)]
>>> quadrados
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
>>>

A variável x assume os valores de 1 a 10, conforme especificado pelo comando for. O valor de x * x é então computado e adicionado à lista que está sendo construída. A sintaxe geral de um preenchimento de lista também permite que um critério de seleção seja adicionado de forma que somente certos itens sejam adicionados. Por exemplo,

>>> quadrados=[x*x for x in range(1,11) if x%2 != 0]
>>> quadrados
[1, 9, 25, 49, 81]
>>>

Esse preenchimento de lista construiu uma lista que contém apenas quadrados dos números ímpares no intervalo de 1 a 10. Qualquer sequência que suporta iteração pode ser usada dentro de um preenchimento de lista para construir uma nova lista.

>>>[c.upper() for c in 'preenchimento' if c not in 'aeiou']
['P', 'R', 'N', 'C', 'H', 'M', 'N', 'T']
>>>

Auto Avaliação

Teste sua compreensão sobre preenchimento de lista refazendo o Activecode 8 usando preenchimentos de lista. Para um desafio extra, veja se você consegue descobrir como remover as duplicatas.

Next Section - 1.11. Tratamento de Exceções