Você está na página 1de 121

Python Essentials 1:

Módulo 3
Valores Booleanos, Execução Condicional, Loops, Listas e Processamento de Lista,
Operações Lógicas e Bitwise

Neste módulo, serão abordados os seguintes tópicos:

• o tipo de dados Booleano;


• operadores relacionais;
• tomar decisões em Python (if, if-else, if-elif, else)
• como repetir a execução de código utilizando loops (while, for)
• como executar operações lógicas e bitwise em Python;
• listas em Python (construção, indexação e slicing; manipulação de conteúdo)
• como classificar uma lista usando algoritmos de bubble-sort;
• listas multidimensionais e suas aplicações.

Perguntas e respostas
Um programador escreve um programa e o programa faz perguntas.

Um computador executa o programa e fornece as respostas. O programa deve ser capaz


de reagir de acordo com as respostas recebidas.
Felizmente, os computadores conhecem apenas dois tipos de respostas:

• sim, isto é verdade;


• não, isto é falso.

Nunca obterá uma resposta como Deixe-me pensar...., Não sei, ou Provavelmente sim, mas não
tenho a certeza.

Para fazer perguntas, o Python utiliza um conjunto de operadores muito especiais.


Vamos analisá-los um após outro, ilustrando os seus efeitos em alguns exemplos simples.

Comparação: operador de igualdade


Pergunta: são dois valores iguais?

Para fazer esta pergunta, utiliza o operador == (igual igual).

Não se esqueça desta importante distinção:

• = é um operador de atribuição, por exemplo, a = b atribui a com o valor de b ;


• == é a questão são estes valores iguais?; a == b compara a e b .

É um operador binário com ligação do lado esquerdo. Precisa de dois argumentos


e verifica se são iguais.

Exercícios
Agora vamos fazer algumas perguntas. Tente adivinhar as respostas.

Pergunta #1: Qual é o resultado da seguinte comparação?

2 == 2 Verifique

Pergunta #2: Qual é o resultado da seguinte comparação?

2 == 2. Verifique

Pergunta #3: Qual é o resultado da seguinte comparação?


1 == 2 Verifique

Igualdade: o operador igual a (==)


A função == (igual a) compara os valores de dois operandos. Se forem iguais, o
resultado da comparação é True . Se eles não forem iguais, o resultado da
comparação é False .

Veja a comparação de igualdade abaixo - qual é o resultado desta operação?

var == 0

Note que não podemos encontrar a resposta se não soubermos qual o valor
atualmente armazenado na variável var .

Se a variável tiver sido alterada muitas vezes durante a execução do seu programa, ou
o seu valor inicial for inserido a partir da consola, a resposta a esta pergunta pode ser
dada apenas pelo Python, e apenas em runtime.

Agora imagine um programador que sofre de insónias, e que tem de contar ovelhas
pretas e brancas separadamente enquanto houver exatamente o dobro das ovelhas
pretas do que das brancas.

A questão será a seguinte:

black_sheep == 2 * white_sheep

Devido à baixa prioridade do operador == , a questão deve ser tratada como


equivalente a esta:

black_sheep == (2 * white_sheep)

Então, vamos praticar a sua compreensão do operador == - consegue adivinhar o


output do código abaixo?

var = 0 # Assigning 0 to var


print(var == 0)

var = 1 # Assigning 1 to var


print(var == 0)
Execute o código e verifique se estava certo.

Desigualdade: o operador não igual a (!=)


A função != (não igual) também compara os valores de dois operandos. Aqui está a
diferença: se eles forem iguais, o resultado da comparação é False . Se eles não forem
iguais, o resultado da comparação é True .

Agora dê uma vista de olhos na comparação de desigualdade em baixo - consegue


adivinhar o resultado desta operação?

var = 0 # Assigning 0 to var


print(var != 0)

var = 1 # Assigning 1 to var


print(var != 0)

Execute o código e verifique se estava certo.

Operadores de comparação: maior que


Pode também fazer uma pergunta de comparação usando o operador > (maior que).

Se quiser saber se há mais ovelhas pretas do que brancas, pode escrevê-lo da seguinte forma:

black_sheep > white_sheep # Greater than

True confirma-o; False nega-o.

Operadores de comparação: maior que ou igual a


O operador maior que tem outra variante especial, não estrita, mas é denotada de forma
diferente da notação aritmética clássica: >= (maior que ou igual a)

Existem dois sinais subsequentes, não um.


Ambos os operadores (estritos e não-estritos), bem como os outros dois discutidos na próxima
secção, são operadores binários com ligação à esquerda, e a sua prioridade é maior do que
a mostrada por == e != .

Se quisermos descobrir se temos ou não de usar um chapéu quente, fazemos a seguinte


pergunta:

centigrade_outside ≥ 0.0 # Greater than or equal to

Operadores de comparação: menor que ou igual a


Como já deve ter adivinhado, os operadores utilizados neste caso são: o < (less than) operator
and its non-strict sibling: <= (menor que ou igual a).

Veja este exemplo simples:

current_velocity_mph < 85 # Less than


current_velocity_mph ≤ 85 # Less than or equal to

Vamos verificar se existe o risco de ser multado pela polícia rodoviária (a primeira pergunta é
rigorosa, a segunda não).

Fazer uso das respostas


O que pode fazer com a resposta (ou seja, o resultado de uma operação de comparação) que
obtém do computador?

Há pelo menos duas possibilidades: primeiro, pode memorizá-la (armazená-la numa


variável) e utilizá-la mais tarde. Como se faz isso? Bem, utilizaria uma variável arbitrária como
esta:

answer = number_of_lions >= number_of_lionesses

O conteúdo da variável dar-lhe-á a resposta à pergunta feita.

A segunda possibilidade é mais conveniente e muito mais comum: pode usar a resposta que
obtém para tomar uma decisão sobre o futuro do programa.
Precisa de uma instrução especial para este fim, e discutiremos isso muito em breve.

Agora precisamos de atualizar a nossa tabela de prioridades e colocar todos os novos


operadores na mesma. Agora parece-se com o seguinte:

Prioridade Operador
1 +, - unário
2 **
3 * , / , // , %
4 +, - binário
5 < , <= , > , >=
6 == , !=

LAB

Tempo estimado
5-10 minutos

Nível de dificuldade
Muito fácil

Objetivos
• familiarizar-se com a função input() ;
• familiarizar-se com os operadores de comparação em Python.

Cenário
Usando um dos operadores de comparação em Python, escreva um programa simples
de duas linhas que toma o parâmetro n como input, que é um inteiro, e
imprime False Se n for menor que 100 , e True Se n for maior ou igual que 100 .

Não crie blocos if nenhuns (vamos falar deles muito em breve). Teste o seu código
utilizando os dados que lhe fornecemos.

Dados de teste

Input de amostra: 55
Output esperado: False

Input de amostra: 99

Output esperado: False

Input de amostra: 100

Output esperado: True

Input de amostra: 101

Output esperado: True

Input de amostra: -5

Output esperado: False

Input de amostra: +123

Output esperado: True

Condições e execução condicional


Já sabe como fazer perguntas ao Python, mas ainda não sabe como fazer um uso razoável das
respostas. Tem de ter um mecanismo que lhe permita fazer algo se uma condição for
cumprida, e não o fazer se não o for.
É como na vida real: faz-se ou não certas coisas quando uma condição específica é cumprida ou
não, por exemplo, vai-se passear se o tempo estiver bom, ou fica-se em casa se estiver a chover
e a fazer frio.

Para tomar tais decisões, o Python oferece uma instrução especial. Devido à sua natureza e à
sua aplicação, chama-se instrução condicional (ou declaração condicional).

Existem várias variantes da mesma. Vamos começar com a mais simples, aumentando a
dificuldade lentamente.

A primeira forma de uma declaração condicional, que pode ver abaixo, é escrita de forma
muito informal mas figurativa:

if true_or_not:
do_this_if_true

Esta declaração condicional consiste nos seguintes elementos, estritamente necessários,


apenas nesta e nesta ordem:

• a keyword if ;
• um ou mais espaços em branco;
• uma expressão (uma pergunta ou uma resposta) cujo valor será interpretado
unicamente em termos de True (quando o seu valor é diferente de zero)
e False (quando é igual a zero);
• um dois pontos seguido de uma newline;
• uma instrução indentada ou conjunto de instruções (pelo menos uma instrução é
absolutamente necessária); a indentação pode ser conseguida de duas maneiras -
inserindo um determinado número de espaços (a recomendação é utilizar quatro
espaços de indentação), ou utilizando o caratere tab; nota: se houver mais de uma
instrução na parte indentada, a indentação deve ser a mesma em todas as linhas;
mesmo que possa parecer a mesma se usar tabs misturados com espaços, é importante
fazer todas as indentações exatamente iguais - o Python 3 não permite a mistura de
espaços e tabs para indentação.

Como funciona essa declaração?

• Se a expressão true_or_not representa a verdade (ou seja, o seu valor não é igual
a zero), a(s) declaração(ões) indentada(s) será(ão) executada(s);
• se a expressão true_or_not não representa a verdade (ou seja, o seu valor é igual a
zero), a(s) declaração(ões) indentada(s) será(ão) omitida(s) (ignoradas), e a
próxima instrução executada será a que se segue ao nível da indentação original.

Na vida real, expressamos frequentemente um desejo:

se o tempo estiver bom, vamos dar um passeio


depois, vamos almoçar

Como se pode ver, almoçar não é uma atividade condicional e não depende do tempo.

Sabendo que condições influenciam o nosso comportamento, e assumindo que temos as


funções sem parâmetros go_for_a_walk() e have_lunch() , podemos escrever o seguinte
snippet:

if the_weather_is_good:
go_for_a_walk()
have_lunch()

Execução condicional: a declaração if .


Se um certo programador de Python insonioso acabar por adormecer enquanto conta 120
ovelhas, e se este procedimento de indução do sono pudesse ser implementado como uma
função especial chamada sleep_and_dream() , todo o código assumiria a seguinte forma:

if sheep_counter >= 120: # Evaluate a test expression


sleep_and_dream() # Execute if test expression is True

Pode lê-lo como: se sheep_counter é maior que ou igual a 120 , então, adormecer e sonhar
(ou seja, executar a função sleep_and_dream .)

Dissemos que as declarações executadas condicionalmente têm de ser indentadas. Isto


cria uma estrutura muito legível, demonstrando claramente todos os caminhos de execução
possíveis no código.

Dê uma vista de olhos no seguinte código:

if sheep_counter >= 120:


make_a_bed()
take_a_shower()
sleep_and_dream()
feed_the_sheepdogs()

Como pode ver, fazer a cama, tomar um banho, e adormecer e sonhar, são todos executados
condicionalmente - quando se sheep_counter atinge o limite desejado.
Alimentar os cães de ovelha, no entanto, é sempre feito (ou seja, a
função feed_the_sheepdogs() não é indentada e não pertence ao bloco if , o que significa
que é sempre executada.)

Agora, vamos discutir outra variante da declaração condicional, que também lhe permite
executar uma ação adicional quando a condição não for cumprida.

Execução condicional: a declaração if-else .


Começámos com uma frase simples, que diz: Se o tempo estiver bom, vamos dar um passeio.

Nota - não há uma palavra sobre o que irá acontecer se o tempo estiver mau. Nós apenas
sabemos que não vamos para o exterior, mas o que poderíamos fazer em vez disso não é
conhecido. Podemos querer planear algo em caso de mau tempo, também.

Podemos dizer, por exemplo: Se o tempo estiver bom, vamos dar uma caminhada, caso
contrário, vamos a um teatro.

Agora sabemos o que iremos fazer se as condições forem cumpridas, e sabemos o que
iremos fazer se nem tudo correr à nossa maneira. Por outras palavras, temos um “Plano B”.

O Python permite-nos expressar estes planos alternativos. Isto é feito com uma segunda forma,
ligeiramente mais complexa, da declaração condicional, a declaração if-else:

if true_or_false_condition:
perform_if_condition_true
else:
perform_if_condition_false

Assim, há uma nova palavra: else - Esta é uma keyword.

A parte do código que começa com else diz o que fazer se a condição especificada para
o if não for cumprida (observe os dois pontos após a palavra).

A execução if-else é feita da seguinte forma:

• se a condição for avaliada como True (o seu valor não é igual a zero), a
declaração perform_if_condition_true é executada, e a declaração condicional
chega ao fim;
• se a condição for avaliada como False (o seu valor é igual a zero), a
declaração perform_if_condition_false é executada, e a declaração condicional
chega ao fim.

A declaração if-else : execução mais condicional


Ao utilizar esta forma de declaração condicional, podemos descrever os nossos planos da
seguinte forma:

if the_weather_is_good:
go_for_a_walk()
else:
go_to_a_theater()
have_lunch()

Se o tempo estiver bom, vamos dar uma volta. Caso contrário, iremos a uma peça de teatro.
Não importa se o tempo estiver bom ou mau, almoçaremos depois (depois do passeio ou
depois de irmos ao teatro).

Tudo o que dissemos sobre a indentação funciona da mesma forma dentro do ramo else:

if the_weather_is_good:
go_for_a_walk()
have_fun()
else:
go_to_a_theater()
enjoy_the_movie()
have_lunch()

Declarações if-else nested


Agora vamos discutir dois casos especiais da declaração condicional.

Primeiro, considere o caso em que a instrução colocada após a if é outra if .

Leia o que temos planeado para este domingo. Se o tempo estiver bom, vamos dar uma volta.
Se encontrarmos um bom restaurante, almoçaremos lá. Caso contrário, comemos uma sandes.
Se o tempo estiver mau, vamos ao teatro. Se não houver bilhetes, iremos às compras no centro
comercial mais próximo.

Vamos escrever o mesmo em Python. Considere cuidadosamente o código aqui:

if the_weather_is_good:
if nice_restaurant_is_found:
have_lunch()
else:
eat_a_sandwich()
else:
if tickets_are_available:
go_to_the_theater()
else:
go_shopping()
Aqui estão dois pontos importantes:

• este uso da declaração if é conhecido como nesting; lembre-se que


cada else refere-se ao if que se situa ao mesmo nível de indentação; é preciso
saber isto para determinar como os ifs e elses se emparelham;
• considere como a indentação melhora a legibilidade, e torna o código mais fácil de
compreender e rastrear.

A declaração elif .
O segundo caso especial introduz outra nova keyword de Python: elif. Como provavelmente
suspeitará, é uma forma mais curta de else if.

elif é usado para verificar mais do que uma condição, e para parar quando a primeira
afirmação que é verdadeira é encontrada.

O nosso próximo exemplo assemelha-se a nesting, mas as semelhanças são muito ligeiras. Mais
uma vez, vamos mudar os nossos planos e expressá-los como se segue: Se o tempo estiver bom,
iremos dar um passeio, caso contrário, se conseguirmos bilhetes, iremos ao teatro, caso
contrário, se houver mesas livres no restaurante, iremos almoçar; se tudo o resto falhar,
regressaremos a casa e jogaremos xadrez.

Já reparou quantas vezes utilizámos as palavras caso contrário? Esta é a fase em que a
keyword elif desempenha o seu papel.

Vamos escrever o mesmo cenário usando Python:

if the_weather_is_good:
go_for_a_walk()
elif tickets_are_available:
go_to_the_theater()
elif table_is_available:
go_for_lunch()
else:
play_chess_at_home()

A forma de reunir as declarações subsequentes if-elif-else é por vezes chamada


de cascade (cascata).

Repare novamente como a indentação melhora a legibilidade do código.

Neste caso, deve ser dada alguma atenção adicional:

• não deve usar else sem um precedente if ;


• else é sempre o último ramo da cascade, independentemente de ter
utilizado elif ou não;
• else é uma parte opcional da cascade, e pode ser omitida;
• se houver um else ramo na cascade, apenas um de todos os ramos é executado;
• se não houver nenhum else ramo, é possível que nenhuma das ramificações
disponíveis seja executada.

Isto pode parecer um pouco confuso, mas esperemos que alguns exemplos simples ajudem a
lançar mais luz.

Análise de amostras de código


Agora vamos mostrar-lhe alguns programas simples mas completos. Não os
explicaremos em detalhe, porque consideramos os comentários (e os nomes das
variáveis) dentro do código guias suficientes.

Todos os programas resolvem o mesmo problema - eles encontram o maior de


vários números e imprimem-no.

Exemplo 1:

Vamos começar com o caso mais simples - como identificar o maior de dois
números:

# Read two numbers


number1 = int(input("Enter the first number: "))
number2 = int(input("Enter the second number: "))

# Choose the larger number


if number1 > number2:
larger_number = number1
else:
larger_number = number2

# Print the result


print("The larger number is:", larger_number)

O snippet acima deve ser claro - ele lê dois valores inteiros, compara-os e descobre
qual é o maior.

Exemplo 2:
Agora vamos mostrar-lhe um facto intrigante. O Python tem uma característica
interessante, veja o código abaixo:

# Read two numbers


number1 = int(input("Enter the first number: "))
number2 = int(input("Enter the second number: "))

# Choose the larger number


if number1 > number2: larger_number = number1
else: larger_number = number2

# Print the result


print("The larger number is:", larger_number)

Nota: se algum dos ramos if-elif-else contiver apenas uma instrução, pode codificá-la
de uma forma mais abrangente (não precisa de fazer uma linha indentada após a
keyword, mas apenas continuar a linha após os dois pontos).

Este estilo, contudo, pode ser enganador, e não o vamos utilizar nos nossos futuros
programas, mas vale definitivamente a pena saber se quiser ler e compreender os
programas de outra pessoa.

Não há outras diferenças no código.

Exemplo 3:

É altura de complicar o código - vamos encontrar o maior de três números. Será que
vai ampliar o código? Um pouco.

Assumimos que o primeiro valor é o maior. Em seguida, verificamos essa hipótese


com os dois valores restantes.

Veja o código abaixo:

# Read three numbers


number1 = int(input("Enter the first number: "))
number2 = int(input("Enter the second number: "))
number3 = int(input("Enter the third number: "))

# We temporarily assume that the first number


# is the largest one.
# We will verify this soon.
largest_number = number1

# We check if the second number is larger than current


largest_number
# and update largest_number if needed.
if number2 > largest_number:
largest_number = number2

# We check if the third number is larger than current


largest_number
# and update largest_number if needed.
if number3 > largest_number:
largest_number = number3

# Print the result


print("The largest number is:", largest_number)

Este método é significativamente mais simples do que tentar encontrar o maior


número ao mesmo tempo, comparando todos os pares de números possíveis (ou seja,
o primeiro com o segundo, o segundo com o terceiro, o terceiro com o primeiro).
Tente reconstruir o código por si mesmo.

Pseudo-código e introdução aos loops


Deverá agora ser capaz de escrever um programa que encontre o maior de quatro, cinco, seis,
ou mesmo dez números.

Já conhece o esquema, pelo que alargar a dimensão do problema não será particularmente
complexo.

Mas o que acontece se lhe pedirmos para escrever um programa que encontre o maior de
duzentos números? Consegue imaginar o código?

Vai precisar de duzentas variáveis. Se duzentas variáveis não for suficientemente mau, tente
imaginar a procura do maior de um milhão de números.

Imagine um código que contém 199 declarações condicionais e duzentas invocações da


função input() . Felizmente, não precisa de lidar com isso. Há uma abordagem mais simples.
Vamos ignorar os requisitos da sintaxe Python por agora, e tentar analisar o problema sem
pensar na programação real. Por outras palavras, vamos tentar escrever o algoritmo, e
quando estivermos satisfeitos com ele, vamos implementá-lo.

Neste caso, utilizaremos uma espécie de notação que não é uma linguagem de programação
real (não pode ser compilada nem executada), mas que é formalizada, concisa e legível. Chama-
se pseudo-código.

Vejamos o nosso pseudo-código abaixo:

largest_number = -999999999
number = int(input())
if number == -1:
print(largest_number)
exit()
if number > largest_number:
largest_number = number
# Go to line 02

O que está a acontecer nele?

Em primeiro lugar, podemos simplificar o programa se, logo no início do código, atribuirmos a
variável largest_number com um valor que será menor do que qualquer um dos números
introduzidos. Vamos usar -999999999 para esse fim.

Em segundo lugar, assumimos que o nosso algoritmo não saberá antecipadamente quantos
números serão entregues ao programa. Esperamos que o utilizador introduza quantos
números quiser - o algoritmo funcionará bem com cem e com mil números. Como é que
fazemos isso?

Fazemos um acordo com o utilizador: quando o valor -1 é introduzido, será um sinal de que
não há mais dados e que o programa deve terminar o seu trabalho.

Caso contrário, se o valor introduzido não for igual a -1 , o programa irá ler outro número, e
assim por diante.

O truque baseia-se no pressuposto de que qualquer parte do código pode ser executada mais
do que uma vez - precisamente, tantas vezes quantas forem necessárias.

A execução de uma determinada parte do código mais do que uma vez é chamada um loop. O
significado deste termo é provavelmente óbvio para si.

Linhas 02 através 08 fazem um loop. Passaremos por eles tantas vezes quantas forem
necessárias para rever todos os valores introduzidos.

Pode usar uma estrutura semelhante num programa escrito em Python? Sim, pode.

Informação Extra

O Python vem muitas vezes com muitas funções incorporadas que farão o trabalho por si. Por
exemplo, para encontrar o maior número de todos, pode usar uma função integrada Python
chamada max() . Pode utilizá-la com múltiplos argumentos. Analise o código abaixo:

# Read three numbers.


number1 = int(input("Enter the first number: "))
number2 = int(input("Enter the second number: "))
number3 = int(input("Enter the third number: "))

# Check which one of the numbers is the greatest


# and pass it to the largest_number variable.

largest_number = max(number1, number2, number3)

# Print the result.


print("The largest number is:", largest_number)

Da mesma forma, pode usar a função min() para devolver o menor número. Pode reconstruir
o código acima e fazer experiências com ele na Sandbox.
Vamos falar sobre estas (e muitas outras) funções em breve. Por enquanto, o nosso foco será
colocado na execução condicional e nos loops para lhe permitir ganhar mais confiança na
programação e ensinar-lhe as competências que lhe permitirão compreender e aplicar
plenamente os dois conceitos no seu código. Portanto, por agora, não vamos por atalhos.

LAB

Tempo estimado
5-15 minutos

Nível de dificuldade
Fácil

Objetivos
• familiarizar-se com a função input() ;
• familiarizar-se com operadores de comparação em Python;
• familiarizar-se com o conceito de execução condicional.

Cenário
O Spathiphyllum, mais vulgarmente conhecido como o lírio de paz ou a planta de vela
branca, é uma das mais populares plantas de interior, capaz de filtrar toxinas nocivas
do ar. Algumas das toxinas que neutraliza incluem o benzeno, o formaldeído e o
amoníaco.

Imagine que o seu programa de computador adora estas plantas. Sempre que recebe
um input na forma da palavra Spathiphyllum , involuntariamente grita para a consola
a seguinte string: "Spathiphyllum is the best plant ever!"

Escreve um programa que utilize o conceito de execução condicional, toma uma string
como entrada, e:

• imprime a frase "Yes - Spathiphyllum is the best plant ever!" para o


ecrã, se a cadeia de caracteres inseridos é "Spathiphyllum" (upper-case)
• Impressões "No, I want a big Spathiphyllum!" se a cadeia de caracteres
inseridos é "spathiphyllum" (lower-case)
• Impressões "Spathiphyllum! Not [input]!" caso contrário.
Nota: [input] é a string tomada como input.

Teste o seu código utilizando os dados que lhe fornecemos. E arranje também um
Spathiphyllum!

Dados de Teste
Input de amostra: spathiphyllum

Output esperado: No, I want a big Spathiphyllum!

Input de amostra: pelargonium

Output esperado: Spathiphyllum! Not pelargonium!

Input de amostra: Spathiphyllum

Output esperado: Yes - Spathiphyllum is the best plant ever!

LAB
Tempo estimado
10-20 minutos

Nível de dificuldade
Fácil/Médio

Objetivos
Familiarizar o aluno a:

• utilizar a instrução if-else para ramificar o caminho de controlo;


• construir um programa completo que resolva problemas simples da vida real.

Cenário
Era uma vez uma terra - uma terra de leite e mel, habitada por pessoas felizes e
prósperas. As pessoas pagavam impostos, claro - a sua felicidade tinha limites. O
imposto mais importante, denominado Imposto sobre o Rendimento das Pessoas
Singulares (IRS ou, em inglês, PIT), tinha de ser pago uma vez por ano, e foi avaliado
utilizando a seguinte regra:

• se o rendimento do cidadão não fosse superior a 85.528 thalers, o imposto era


igual a 18% do rendimento menos 556 thalers e 2 cêntimos (este era o
chamado desagravamento fiscal (em inglês, tax relief))
• se o rendimento fosse superior a este montante, o imposto seria igual a 14.839
thalers e 2 cêntimos, mais 32% do excedente acima de 85.528 thalers.

A sua tarefa é escrever uma calculadora de impostos.

• Deve aceitar um valor de floating-point: o rendimento.


• A seguir, deve imprimir o imposto calculado, arredondado a thalers completos.
Há uma função chamada round() que lhe fará o arredondamento por si -
encontrá-la-á no código esqueleto no editor.

Nota: este país feliz nunca devolve dinheiro aos seus cidadãos. Se o imposto calculado
for inferior a zero, significa apenas que não há qualquer imposto (o imposto é igual a
zero). Tenha isto em consideração durante os seus cálculos.

Veja o código no editor - lê apenas um valor de input e faz output de um resultado,


pelo que necessita de o completar com alguns cálculos inteligentes.

Teste o seu código utilizando os dados por nós fornecidos.

Dados de teste
Input de amostra: 10000

Output esperado: The tax is: 1244.0 thalers

Input de amostra: 100000

Output esperado: The tax is: 19470.0 thalers

Input de amostra: 1000

Output esperado: The tax is: 0.0 thalers

Input de amostra: -100

Output esperado: The tax is: 0.0 thalers

LAB

Tempo estimado
10-25 minutos

Nível de dificuldade
Fácil/Médio
Objetivos
Familiarizar o aluno a:

• a utilização do loop if-elif-else ;


• encontrar a correta implementação de regras definidas verbalmente;
• testar código utilizando input e output de amostra.

Cenário
Como certamente sabe, devido a algumas razões astronómicas, os anos podem
ser bissextos ou comuns. Os primeiros têm 366 dias de duração, enquanto os
segundos têm 365 dias de duração.

Desde a introdução do calendário gregoriano (em 1582), a seguinte regra é utilizada


para determinar o tipo de ano:

• se o número do ano não for divisível por quatro, é um ano comum;


• caso contrário, se o número do ano não for divisível por 100, é um ano
bissexto;
• caso contrário, se o número do ano não for divisível por 400, é um ano comum;
• caso contrário, é um ano bissexto.

Veja o código no editor - lê apenas um número de ano, e precisa de ser completado


com as instruções de implementação do teste que acabámos de descrever.

O código deve fazer output de uma de duas mensagens possíveis, que são Leap
year ou Common year , dependendo do valor inserido.

Seria bom verificar se o ano introduzido cai na era Gregoriana, e faz output de um
aviso caso contrário: Not within the Gregorian calendar period . Dica: use os
operadores != e % .

Teste o seu código utilizando os dados por nós fornecidos.

Dados de teste
Input de amostra: 2000

Output esperado: Leap year

Input de amostra: 2015

Output esperado: Common year


Input de amostra: 1999

Output esperado: Common year

Input de amostra: 1996

Output esperado: Leap year

Input de amostra: 1580

Output esperado: Not within the Gregorian calendar period

Key takeaways

1. Os operadores de comparação (ou os chamados relacionais) são usados para comparar


valores. A tabela abaixo ilustra como os operadores de comparação funcionam, assumindo
que x = 0 , y = 1 , e z = 0 :

Operador Descrição Exemplo


x == y # False
==
retorna se os valores dos operandos forem iguais, e False caso
x == z # True
contrário
x != y # True
retorna True se os valores dos operandos não forem iguais,
!= x != z # False
e False caso contrário
x > y # False
True se o
valor do operando esquerdo for maior que o valor do
> y > z # True
operando direito, e False caso contrário
x < y # True
True se o
valor do operando esquerdo for inferior ao valor do
< y < z # False
operando direito, e False caso contrário
x >= y # False
True se ovalor do operando esquerdo for maior ou igual ao x >= z # True

valor do operando direito, e False caso contrário y >= z # True

x <= y # True
True se ovalor do operando esquerdo for inferior ou igual ao x <= z # True

valor do operando direito, e False caso contrário y <= z # False

2. Quando quiser executar algum código apenas se uma determinada condição for cumprida,
pode usar uma declaração condicional:

• uma única if declaração, por exemplo:

x = 10

if x == 10: # condition
print("x is equal to 10") # Executed if the condition is
True.

• uma série de if declarações, por exemplo:

x = 10

if x > 5: # condition one


print("x is greater than 5") # Executed if condition one
is True.

if x < 10: # condition two


print("x is less than 10") # Executed if condition two
is True.

if x == 10: # condition three


print("x is equal to 10") # Executed if condition three
is True.

Cada if declaração é testada separadamente.


• uma if-else declaração, por exemplo:

x = 10

if x < 10: # Condition


print("x is less than 10") # Executed if the condition
is True.

else:
print("x is greater than or equal to 10") # Executed if
the condition is False.

• uma série de if declarações seguidas por um else , por exemplo:

x = 10

if x > 5: # True
print("x > 5")

if x > 8: # True
print("x > 8")

if x > 10: # False


print("x > 10")

else:
print("else will be executed")

Cada if é testado separadamente. O corpo de else é executado se o


último if for False .

• A if-elif-else declaração, por exemplo:

x = 10

if x == 10: # True
print("x == 10")

if x > 15: # False


print("x > 15")
elif x > 10: # False
print("x > 10")

elif x > 5: # True


print("x > 5")

else:
print("else will not be executed")

Se a condição if for False , o programa verifica as condições dos elif blocos


subsequentes - o primeiro elif bloco que True é executado. Se todas as condições
forem False , o else bloco será executado.

• Declarações condicionais nested, por exemplo:

x = 10

if x > 5: # True
if x == 6: # False
print("nested: x == 6")
elif x == 10: # True
print("nested: x == 10")
else:
print("nested: else")
else:
print("else")

Key takeaways: continuação

Exercício 1

Qual é o output do seguinte snippet?

x = 5
y = 10
z = 8

print(x > y)
print(y > z)

Verifique

Exercício 2
Qual é o output do seguinte snippet?

x, y, z = 5, 10, 8

print(x > z)
print((y - 5) == x)

Verifique

Exercício 3

Qual é o output do seguinte snippet?

x, y, z = 5, 10, 8
x, y, z = z, y, x

print(x > z)
print((y - 5) == x)

Verifique

Exercício 4

Qual é o output do seguinte snippet?

x = 10

if x == 10:
print(x == 10)
if x > 5:
print(x > 5)
if x < 10:
print(x < 10)
else:
print("else")

Verifique

Exercício 5

Qual é o output do seguinte snippet?

x = "1"
if x == 1:
print("one")
elif x == "1":
if int(x) > 1:
print("two")
elif int(x) < 1:
print("three")
else:
print("four")
if int(x) == 1:
print("five")
else:
print("six")

Verifique

Exercício 6

Qual é o output do seguinte snippet?

x = 1
y = 1.0
z = "1"

if x == y:
print("one")
if y == int(z):
print("two")
elif x == y:
print("three")
else:
print("four")

Verifique

Fazer loop ao seu código com while


Concorda com a declaração apresentada abaixo?

while there is something to do


do it

Note-se que este registo também declara que se não houver nada a fazer, nada acontecerá.
Em geral, em Python, um loop pode ser representado da seguinte forma:

while conditional_expression:
instruction

Se notar algumas semelhanças com a instrução if, não há problema. De facto, a diferença
sintática é apenas uma: usa-se a palavra while em vez da palavra if .

A diferença semântica é mais importante: quando a condição é cumprida, if executa as suas


declarações apenas uma vez; while repete a execução enquanto a condição se avalie
a True .

Nota: todas as regras relativas à indentação são aplicáveis também aqui. Vamos mostrar-lhe
isso em breve.

Veja o algoritmo abaixo:

while conditional_expression:
instruction_one
instruction_two
instruction_three
:
:
instruction_n

Agora é importante lembrar que:

• se quiser executar mais do que uma declaração dentro de um while , deve (como
com if ) indentar todas as instruções da mesma forma;
• uma instrução ou conjunto de instruções executadas no interior do loop while é
chamada corpo do loop;
• se a condição é False (igual a zero) logo que é testada pela primeira vez, o corpo não
é executado nem uma vez (note-se a analogia de não ter de fazer nada se não houver
nada a fazer);
• o corpo deve ser capaz de alterar o valor da condição, porque se a condição
estiver True no início, o corpo pode correr continuamente até ao infinito - repare que
fazer uma coisa normalmente diminui o número de coisas a fazer).

Um loop infinito
Um loop infinito, também chamado endless loop, é uma sequência de instruções num
programa que se repete indefinidamente (loop interminável).
Eis um exemplo de um loop que não é capaz de terminar a sua execução:

while True:
print("I'm stuck inside a loop.")

Este loop será infinitamente imprimido "I'm stuck inside a loop." no ecrã.

NOTA

Se quiser obter a melhor experiência de aprendizagem ao ver como se comporta um loop


infinito, lance o IDLE, crie um New File, copie-cole o código acima, guarde o seu ficheiro, e
execute o programa. O que irá ver é a sequência interminável de strings "I'm stuck
inside a loop." impressas na janela da consola do Python. Para terminar o seu programa,
basta premir Ctrl-C (ou Ctrl-Break em alguns computadores). Isto causará a chamada
exceção KeyboardInterrupt e deixa o seu programa sair do loop. Falaremos sobre isso mais
tarde no curso.

Voltemos ao esboço do algoritmo que lhe mostrámos recentemente. Vamos mostrar-lhe como
utilizar este loop recentemente aprendido para encontrar o maior número a partir de um
grande conjunto de dados introduzidos.

Analise o programa com cuidado. Veja onde o loop começa (linha 8). Localize o corpo do loop e
descubra como é que o corpo sai:

# Store the current largest number here.


largest_number = -999999999

# Input the first value.


number = int(input("Enter a number or type -1 to stop: "))

# If the number is not equal to -1, continue.


while number != -1:
# Is number larger than largest_number?
if number > largest_number:
# Yes, update largest_number.
largest_number = number
# Input the next number.
number = int(input("Enter a number or type -1 to stop: "))

# Print the largest number.


print("The largest number is:", largest_number)

Verifique como este código implementa o algoritmo que lhe mostrámos anteriormente.
Os loops loop while : mais exemplos

Vejamos outro exemplo empregando o loop while . Siga os comentários para


descobrir a ideia e a solução.

# A program that reads a sequence of numbers


# and counts how many numbers are even and how many are odd.
# The program terminates when zero is entered.

odd_numbers = 0
even_numbers = 0

# Read the first number.


number = int(input("Enter a number or type 0 to stop: "))

# 0 terminates execution.
while number != 0:
# Check if the number is odd.
if number % 2 == 1:
# Increase the odd_numbers counter.
odd_numbers += 1
else:
# Increase the even_numbers counter.
even_numbers += 1
# Read the next number.
number = int(input("Enter a number or type 0 to stop: "))

# Print results.
print("Odd numbers count:", odd_numbers)
print("Even numbers count:", even_numbers)

Certas expressões podem ser simplificadas sem alterar o comportamento do


programa.

Tente lembrar-se de como o Python interpreta a verdade de uma condição e observe


que estas duas formas são equivalentes:

while number != 0: e while number: .

A condição que verifica se um número é ímpar também pode ser codificada nestas
formas equivalentes:

if number % 2 == 1: e if number % 2: .
Usar uma variável counter para sair de um loop
Veja o snippet abaixo:

counter = 5
while counter != 0:
print("Inside the loop.", counter)
counter -= 1
print("Outside the loop.", counter)

Este código destina-se a imprimir a string "Inside the loop." e o valor armazenado
na variável counter durante um determinado loop exatamente cinco vezes. Uma vez
que a condição não foi atendida (a variável counter atingiu 0 ), o loop é encerrado, e a
mensagem "Outside the loop." bem como o valor armazenado em counter é
impresso.

Mas há uma coisa que pode ser escrita de forma mais compacta - a condição do
loop while .

Consegue ver a diferença?

counter = 5
while counter:
print("Inside the loop.", counter)
counter -= 1
print("Outside the loop.", counter)

É mais compacto do que anteriormente? Um pouco. É mais legível? Isso é discutível.

LEMBRE-SE

Não se sinta obrigado a codificar os seus programas de uma forma que seja sempre a
mais curta e a mais compacta. A legibilidade pode ser um fator mais importante.
Mantenha o seu código preparado para um novo programador.
LAB

Tempo estimado
15 minutos

Nível de dificuldade
Fácil

Objetivos
Familiarizar o aluno a:

• a utilização do loop while ;


• refletir situações da vida real em código informático.

Cenário
Um mágico júnior escolheu um número secreto. Ele escondeu-o numa variável
chamada secret_number . Ele quer que todos os que executam o seu programa
joguem o jogo do Adivinhe o número secreto, e adivinhe que número escolheu para
eles. Aqueles que não adivinharem o número ficarão presos num loop infinito para
sempre! Infelizmente, ele não sabe como completar o código.

A sua tarefa é ajudar o mágico a completar o código no editor, de modo a que o


código:

• peça ao utilizador para introduzir um número inteiro;


• utilize um loop while ;
• verifique se o número introduzido pelo utilizador é o mesmo que o número
escolhido pelo mágico. Se o número escolhido pelo utilizador for diferente do
número secreto do mágico, o utilizador deve ver a mensagem "Ha ha!
You're stuck in my loop!" e ser solicitado a introduzir novamente um
número. Se o número introduzido pelo utilizador corresponder ao número
escolhido pelo mágico, o número deve ser impresso no ecrã, e o mágico deve
dizer as seguintes palavras: "Well done, muggle! You are free now."

The magician is counting on you! Não o dececione.

INFORMAÇÃO EXTRA
A propósito, olha para a função print() . A forma como a utilizámos aqui chama-
se impressão multi-linha. Pode usar aspas triplas para imprimir strings em várias
linhas a fim de tornar o texto mais fácil de ler, ou criar um desenho especial baseado
em texto. Experimente-o.

Fazer loop ao seu código com for


Outro tipo de loop disponível em Python vem da observação de que por vezes é mais
importante contar as "voltas" do loop do que verificar as condições.

Imagine que o corpo de um loop precisa de ser executado exatamente cem vezes. Se desejar
utilizar o loop while para o fazer, pode ser assim:

i = 0
while i < 100:
# do_something()
i += 1

Seria bom se alguém pudesse fazer esta contagem aborrecida por si. Isso é possível?

Claro que é - há um loop especial para estes tipos de tarefas, e é chamado for .

Na verdade, o loop for foi concebido para realizar tarefas mais complicadas - pode "navegar"
por grandes coleções de dados item por item. Mostraremos como fazê-lo em breve, mas
neste momento vamos apresentar uma variante mais simples da sua aplicação.
Dê uma vista de olhos no snippet:

for i in range(100):
# do_something()
pass

Existem alguns novos elementos. Deixe-nos falar sobre eles:

• a keyword for abre o loop for ; nota - não há nenhuma condição depois; não é preciso
pensar nas condições, uma vez que são verificadas internamente, sem qualquer
intervenção;
• qualquer variável após a keyword for é a variável de controlo do loop; conta as voltas
do loop, e fá-lo automaticamente;
• a keyword in introduz um elemento de sintaxe que descreve a gama de valores
possíveis que estão a ser atribuídos à variável de controlo;
• a função range() (esta é uma função muito especial) é responsável por gerar todos
os valores desejados da variável de controlo; no nosso exemplo, a função irá criar
(podemos mesmo dizer que irá alimentar o loop com) valores subsequentes a partir
do conjunto seguinte: 0, 1, 2 .. 97, 98, 99; nota: neste caso, a função range() começa o
seu trabalho a partir do 0 e termina um passo (um número inteiro) antes do valor do
seu argumento;
• note a keyword pass dentro do corpo do loop - não faz nada; é uma instrução vazia -
colocamo-la aqui porque a for sintaxe do laço exige pelo menos uma instrução dentro
do corpo (a propósito - if , elif , else e while expressam a mesma coisa)

Os nossos próximos exemplos serão um pouco mais modestos no número de repetições do


loop.

Veja o snippet abaixo. Consegue prever o seu output?

for i in range(10):
print("The value of i is currently", i)

Execute o código para verificar se estava certo.

Nota:

• o loop foi executado dez vezes (é o argumento da função range() )


• o valor da última variável de controlo é 9 (não 10 , visto começar a partir de 0 , não a
partir de 1 )
A função range() pode ser equipada com dois argumentos, e não apenas um:

for i in range(2, 8):


print("The value of i is currently", i)

Neste caso, o primeiro argumento determina o (primeiro) valor inicial da variável de controlo.

O último argumento mostra o primeiro valor que a variável de controlo não será atribuída.

Nota: a função range() aceita apenas inteiros como seus argumentos, e gera sequências
de inteiros.

Consegue adivinhar o output do programa? Execute-o para verificar se também estava certo
agora.

O primeiro valor mostrado é 2 (retirado do primeiro argumento range() .)

O último é 7 (embora o range() segundo argumento seja 8 ).

Mais sobre o loop for e a range() função com três


argumentos
A função range() também pode aceitar três argumentos - dê uma vista de olhos ao
código no editor.

O terceiro argumento é um incremento - é um valor acrescentado para controlar a


variável em cada volta do loop (como se pode suspeitar, o valor por defeito do
incremento é 1).

Consegue dizer-nos quantas linhas irão aparecer na consola, e que valores irão
conter?

Execute o programa para saber se estava certo.

Deve ser capaz de ver as seguintes linhas na janela da consola:

The value of i is currently 2


The value of i is currently 5

output
Sabe porquê? O primeiro argumento passado para a função range() diz-nos qual
o número inicial da sequência (logo, 2 no output). O segundo argumento informa
à função onde parar a sequência (a função gera números até ao número indicado
pelo segundo argumento, mas não o inclui). Finalmente, o terceiro argumento
indica a etapa, que na realidade significa a diferença entre cada número na
sequência de números gerados pela função.

2 (número inicial) → 5 ( 2 incremento de 3 é igual a 5 - o número está dentro do intervalo de 2


a 8) → 8 ( 5 incremento de 3 é igual a 8 - o número não está dentro do intervalo de 2 a 8,
porque o parâmetro stop não está incluído na sequência de números gerados pela função.)

Nota: se o conjunto gerado pela função range() está vazio, o loop não irá executar de todo o
seu corpo.

Tal como aqui - não haverá output:

for i in range(1, 1):


print("The value of i is currently", i)

Nota: o conjunto gerado pelo range() tem de estar ordenado por ordem crescente. Não há
como forçar o range() a criar um conjunto de uma forma diferente quando a
função range() aceita exatamente dois argumentos. Isto significa que o segundo argumento
de range() deve ser maior que o primeiro.

Logo, também não haverá output aqui:

for i in range(2, 1):


print("The value of i is currently", i)

Vamos dar uma vista de olhos num programa curto, cuja tarefa é escrever algumas das
primeiras potências de dois:

power = 1
for expo in range(16):
print("2 to the power of", expo, "is", power)
power *= 2

A expo variável é usada como uma variável de controlo para o loop, e indica o valor atual
do expoente. A exponenciação em si é substituída pela multiplicação por dois. Uma vez que 20 é
igual a 1, então 2 x; 1 é igual a 21, 2 x; 21 é igual a 22, e assim por diante. Qual é o maior
expoente para o qual o nosso programa ainda imprime o resultado?

Execute o código e verifique se o output corresponde às suas expetativas.

LAB

Tempo estimado
5-15 minutos

Nível de dificuldade
Muito fácil

Objetivos
Familiarizar o aluno a:

• a utilização do loop for ;


• refletir situações da vida real em código informático.

Cenário
Sabe o que é o Mississippi? Bem, é o nome de um dos estados e rios dos Estados
Unidos. O rio Mississippi tem cerca de 3.765 quilómetros de comprimento, o que o
torna o segundo rio mais longo dos Estados Unidos (o mais longo sendo o rio
Missouri). É tão longo que uma única gota de água precisa de 90 dias para percorrer
toda a sua extensão!

A palavra Mississippi é também usada para um propósito ligeiramente


diferente: contar mississippily.

Se não está familiarizado com a frase, estamos aqui para lhe explicar o seu significado:
é usado para contar segundos.

A ideia por detrás disto é que adicionar a palavra Mississippi a um número ao contar
segundos em voz alta faz com que soem mais perto do tempo do relógio, e por isso
"um Mississippi, dois Mississippi, três Mississippi" levará aproximadamente três
segundos de tempo real! É frequentemente utilizado por crianças que brincam às
escondidas para garantir que o buscador faz uma contagem honesta.
A sua tarefa aqui é muito simples: escreva um programa que utilize um loop for para
“contar mississippily” até cinco. Tendo contado até cinco, o programa deve imprimir
para o ecrã a mensagem final "Ready or not, here I come!"

Use o esqueleto que fornecemos no editor.

INFORMAÇÃO EXTRA

Observe que o código no editor contém dois elementos que podem não estar
totalmente claros para si neste momento: a declaração import time , e o
método sleep() . Vamos falar sobre eles em breve.

Por enquanto, gostaríamos apenas que soubesse que importámos o módulo time e
usámos o método sleep() para suspender a execução de cada
função print() subsequente dentro do loop for por um segundo, para que a
mensagem enviada para a consola se assemelhe a uma contagem real. Não se
preocupe - em breve aprenderá mais sobre módulos e métodos.

Output esperado
1 Mississippi
2 Mississippi
3 Mississippi
4 Mississippi
5 Mississippi

Os loops break e declarações continue .


Até agora, temos tratado o corpo do loop como uma sequência indivisível e
inseparável de instruções que são executadas completamente a cada volta do loop.
No entanto, como programador, poderá ser confrontado com as seguintes escolhas:

• parece que é desnecessário continuar o loop como um todo; deve abster-se de


continuar a execução do corpo do loop e continuar;
• parece que é necessário iniciar a próxima volta do loop sem completar a
execução da volta atual.
O Python fornece duas instruções especiais para a execução de ambas estas tarefas.
Digamos, por uma questão de precisão, que a sua existência na linguagem não é
necessária - um programador experiente é capaz de codificar qualquer algoritmo sem
estas instruções. Tais adições, que não melhoram o poder expressivo da linguagem,
mas apenas simplificam o trabalho do programador, são por vezes chamadas
de doces sintáticos, ou açúcar sintático.

Estas duas instruções são:

• break - sai imediatamente do loop, e termina incondicionalmente a operação


do loop; o programa começa a executar a instrução mais próxima após o corpo
do loop;
• continue - comporta-se como se o programa tivesse subitamente chegado ao
fim do corpo; inicia-se a volta seguinte e a expressão da condição é testada
imediatamente.

Ambas as palavras são keywords.

Agora vamos mostrar-lhe dois exemplos simples para ilustrar como as duas instruções
funcionam. Veja o código no editor. Execute o programa e analise o output. Modifique
o código e experimente.

Os loops break e declarações continue : mais


exemplos
Voltemos ao nosso programa que reconhece o maior entre os números introduzidos.
Iremos convertê-lo duas vezes, utilizando as instruções break e continue .

Analise o código, e julgue se e como utilizaria qualquer um deles.

A variante break vai aqui:


largest_number = -99999999
counter = 0

while True:
number = int(input("Enter a number or type -1 to end program:
"))
if number == -1:
break
counter += 1
if number > largest_number:
largest_number = number

if counter != 0:
print("The largest number is", largest_number)
else:
print("You haven't entered any number.")

Execute-a, teste-a e experimente com ela.

E agora a variante continue :

largest_number = -99999999
counter = 0

number = int(input("Enter a number or type -1 to end program: "))

while number != -1:


if number == -1:
continue
counter += 1

if number > largest_number:


largest_number = number
number = int(input("Enter a number or type -1 to end program:
"))

if counter:
print("The largest number is", largest_number)
else:
print("You haven't entered any number.")

Olhe cuidadosamente, o utilizador introduz o primeiro número antes de o programa


entrar no loop while . O número subsequente é inserido quando o programa já está
em loop.
Novamente - execute o programa, teste-o e experimente com ele.

LAB

Tempo estimado
10-20 minutos

Nível de dificuldade
Fácil

Objetivos
Familiarizar o aluno a:

• a utilização do loop break em loops;


• refletir situações da vida real em código informático.

Cenário
O comando break é utilizada para sair/terminar um loop.

Crie um programa que use um loop while e pede continuamente ao utilizador para
introduzir uma palavra, a menos que o utilizador introduza "chupacabra" como a
palavra secreta de saída, caso em que a mensagem "You've successfully left
the loop." deve ser impressa para o ecrã, e o loop deve terminar.

Não imprima nenhuma das palavras introduzidas pelo utilizador. Utilize o conceito de
execução condicional e a break declaração.

LAB
Tempo estimado
10-20 minutos

Nível de dificuldade
Fácil

Objetivos
Familiarizar o aluno a:

• a utilização do loop continue em loops;


• refletir situações da vida real em código informático.

Cenário
O comando continue é utilizada para saltar o bloco atual e avançar para a próxima
iteração, sem executar as declarações dentro do loop.

Pode ser utilizada tanto com os loops while e for .

A sua tarefa aqui é muito especial: tem de conceber um vowel eater (comedor de
vogais)! Escreva um programa que use:

• um loop for ;
• o conceito de execução condicional (if-elif-else)
• a declaração continue .

O seu programa deve:

• pedir ao utilizador para introduzir uma palavra;


• usar user_word = user_word.upper() para converter a palavra introduzida
pelo utilizador em maiúsculas; falaremos sobre os chamados métodos de
strings e o método upper() muito em breve - não se preocupe;
• usar execução condicional e a declaração continue para “comer” as seguintes
vogais A, E, I, O, U da palavra introduzida;
• imprimir as letras não comidas para o ecrã, cada uma delas numa linha
separada.

Teste o seu programa com os dados que lhe fornecemos.

Dados de teste
Input de amostra: Gregory

Output esperado:

G
R
G
R
Y

Input de amostra: abstemious

Output esperado:

B
S
T
M
S

LAB

Tempo estimado
5-15 minutos

Nível de dificuldade
Fácil
Objetivos
Familiarizar o aluno a:

• a utilização do loop continue em loops;


• modificar e atualizar o código existente;
• refletir situações da vida real em código informático.

Cenário
A sua tarefa aqui é ainda mais especial do que antes: deve redesenhar o comedor de
vogais (feio) do laboratório anterior (3.1.2.10) e criar um comedor de vogais (bonito)
melhor e mais aperfeiçoado! Escreva um programa que use:

• um loop for ;
• o conceito de execução condicional (if-elif-else)
• a declaração continue .

O seu programa deve:

• pedir ao utilizador para introduzir uma palavra;


• usar user_word = user_word.upper() para converter a palavra introduzida
pelo utilizador em maiúsculas; falaremos sobre os chamados métodos de
strings e o método upper() muito em breve - não se preocupe;
• usar execução condicional e a declaração continue para “comer” as seguintes
vogais A, E, I, O, U da palavra introduzida;
• atribuir as letras não comidas à variável word_without_vowels e imprimir a
variável para o ecrã.

Veja o código no editor. Criámos word_without_vowels e atribuimos-lhe uma string


vazia. Utilize a operação de concatenação para pedir ao Python que combine as letras
selecionadas numa string mais longa durante os loops subsequentes, e atribua-a à
variável word_without_vowels .

Teste o seu programa com os dados que lhe fornecemos.

Dados de teste
Input de amostra: Gregory

Output esperado:

GRGRY
Input de amostra: abstemious

Output esperado:

BSTMS

Os loops while e o ramo else .


Ambos os loops, while e for , têm uma característica interessante (e raramente
usada).

Vamos mostrar-lhe como funciona - tente julgar por si próprio se é utilizável e se pode
viver sem ela ou não.

Por outras palavras, tente convencer-se se a característica é valiosa e útil, ou se é


apenas açúcar sintático.

Veja o snippet no editor. Há algo estranho no final - a keyword else .

Como pode ter suspeitado, os loops podem ter o ramo else também, como if .

O ramo do loop else é sempre executado uma vez, independentemente de o loop


ter entrado no seu corpo ou não.

Consegue adivinhar o output? Execute o programa para verificar se estava certo.

Modifique um pouco o anippet para que o loop não tenha hipótese de executar o seu
corpo nem mesmo uma vez:

i = 5
while i < 5:
print(i)
i += 1
else:
print("else:", i)
A condição while é False no início - consegue vê-la?

Execute e teste o programa, e verifique se o ramo else foi executado ou não.

Os loops for e o ramo else .


for os loops comportam-se de forma um pouco diferente - dê uma vista de olhos ao
snippet no editor e execute-o.

O output pode ser um pouco surpreendente.

A variável i retém o seu último valor.

Modifique um pouco o código para levar a cabo mais uma experiência.

i = 111
for i in range(2, 1):
print(i)
else:
print("else:", i)

Consegue adivinhar o output?

O corpo do loop não será executado aqui. Nota: atribuímos a variável i antes do loop.

Execute o programa e verifique o seu output.

Quando o corpo do loop não é executado, a variável de controlo retém o valor que
tinha antes do loop.

Nota: se a variável de controlo não existir antes do início do loop, não existirá
quando a execução atingir o ramo else .

O que acha desta variante de else ?

Agora vamos falar-lhe de alguns outros tipos de variáveis. As nossas variáveis atuais só
podem armazenar um valor de cada vez, mas há variáveis que podem fazer muito
mais - podem armazenar tantos valores quantos você quiser.
LAB

Tempo estimado
20-30 minutos

Nível de dificuldade
Médio

Objetivos
Familiarizar o aluno a:

• a utilização do loop while ;


• encontrar a correta implementação de regras definidas verbalmente;
• refletir situações da vida real em código informático.

Cenário
Leia esta história: um rapaz e o seu pai, um programador de computador, estão a
brincar com blocos de madeira. Eles estão a construir uma pirâmide.

A sua pirâmide é um pouco estranha, pois na realidade é uma parede em forma de


pirâmide - é plana. A pirâmide é empilhada de acordo com um princípio simples: cada
camada inferior contém mais um bloco do que a camada superior.

A figura ilustra a regra utilizada pelos construtores:

A sua tarefa é escrever um programa que leia o número de blocos que os construtores
têm, e que produza a altura da pirâmide que pode ser construída utilizando estes
blocos.
Nota: a altura é medida pelo número de camadas completamente preenchidas - se
os construtores não tiverem um número suficiente de blocos e não conseguirem
completar a camada seguinte, terminam o seu trabalho imediatamente.

Teste o seu código utilizando os dados por nós fornecidos.

Dados de teste

Input de amostra: 6

Output esperado: The height of the pyramid: 3

Input de amostra: 20

Output esperado: The height of the pyramid: 5

Input de amostra: 1000

Output esperado: The height of the pyramid: 44

Input de amostra: 2

Output esperado: The height of the pyramid: 1


LAB

Tempo estimado
20 minutos

Nível de dificuldade
Médio

Objetivos
Familiarizar o aluno a:

• a utilização do loop while ;


• a conversão de loops definidos verbalmente em código Python real.

Cenário
Em 1937, um matemático alemão chamado Lothar Collatz formulou uma hipótese
intrigante (ainda não provada) que pode ser descrita da seguinte forma:

1. tomar qualquer número inteiro não-negativo e não-nulo e nomeá-lo c0 ;


2. se for par, avalie um novo c0 como c0 ÷ 2 ;
3. caso contrário, se for ímpar, avalie um novo c0 como 3 × c0 + 1 ;
4. Se c0 ≠ 1 , saltar para o ponto 2.

A hipótese diz que, independentemente do valor inicial de c0 , irá sempre para 1.

É claro que é uma tarefa extremamente complexa utilizar um computador para provar
a hipótese de qualquer número natural (pode até requerer inteligência artificial), mas
pode usar o Python para verificar alguns números individuais. Talvez até encontre o
que possa refutar a hipótese.

Escreva um programa que leia um número natural e execute os passos acima


indicados, desde que c0 permaneça diferente de 1. Também queremos que conte os
passos necessários para alcançar o objetivo. O seu código deve fazer output de todos
os valores intermédios de c0 , também.

Dica: a parte mais importante do problema é como transformar a ideia de Collatz num
loop while - esta é a chave para o sucesso.
Teste o seu código utilizando os dados por nós fornecidos.

Dados de teste

Input de amostra: 15

Output esperado:

46
23
70
35
106
53
160
80
40
20
10
5
16
8
4
2
1
steps = 17

Input de amostra: 16

Output esperado:

8
4
2
1
steps = 4

Input de amostra: 1023

Output esperado:

3070
1535
4606
2303
6910
3455
10366
5183
15550
7775
23326
11663
34990
17495
52486
26243
78730
39365
118096
59048
29524
14762
7381
22144
11072
5536
2768
1384
692
346
173
520
260
130
65
196
98
49
148
74
37
112
56
28
14
7
22
11
34
17
52
26
13
40
20
10
5
16
8
4
2
1
steps = 62

Key takeaways

1. Existem dois tipos de loops em Python: while e for :

• o loop while executa uma declaração ou um conjunto de declarações, desde que uma
condição booleana especificada seja verdadeira, por exemplo:

# Example 1
while True:
print("Stuck in an infinite loop.")

# Example 2
counter = 5
while counter > 2:
print(counter)
counter -= 1
• o loop for executa um conjunto de declarações várias vezes; é usado para iterar sobre
uma sequência (por exemplo, uma lista, um dicionário, um tuple, ou um conjunto -
aprenderá sobre eles em breve) ou outros objetos que são iteráveis (por exemplo,
strings). Pode utilizar o loop for para iterar sobre uma sequência de números usando
a função range . Veja os exemplos em baixo:

# Example 1
word = "Python"
for letter in word:
print(letter, end="*")

# Example 2
for i in range(1, 10):
if i % 2 == 0:
print(i)

2. Pode utilizar as declarações break e continue para alterar o fluxo de um loop:

• Utilize break para sair de um loop, por exemplo:

text = "OpenEDG Python Institute"


for letter in text:
if letter == "P":
break
print(letter, end="")

• Utilize continue para ignorar a iteração atual e continuar com a próxima iteração,
por exemplo:

text = "pyxpyxpyx"
for letter in text:
if letter == "x":
continue
print(letter, end="")

3. Os loops while e for também podem ter uma cláusula else em Python. A
cláusula else executa-se após o loop terminar a sua execução, desde que não tenha sido
terminado por break , por exemplo.:
n = 0

while n != 3:
print(n)
n += 1
else:
print(n, "else")

print()

for i in range(0, 3):


print(i)
else:
print(i, "else")

4. O objeto da exceção range() gera uma sequência de números. Aceita números inteiros e
devolve objetos de range. A sintaxe de range() parece como se segue: range(start,
stop, step) , onde:

• start é um parâmetro opcional que especifica o número inicial da sequência (0 por


padrão)
• stop é um parâmetro opcional que especifica o fim da sequência gerada (não está
incluído),
• e step é um parâmetro opcional que especifica a diferença entre os números na
sequência (1 por padrão.)

Código de exemplo:

for i in range(3):
print(i, end=" ") # Outputs: 0 1 2

for i in range(6, 1, -2):


print(i, end=" ") # Outputs: 6, 4, 2

Principais takeaways: continuação


Exercício 1

Crie um loop for que conta de 0 a 10, e imprime os números ímpares no ecrã. Use o esqueleto
abaixo:

for i in range(1, 11):


# Line of code.
# Line of code.
Verifique

Exercício 2

Crie um loop while que conta de 0 a 10, e imprime os números ímpares no ecrã. Use o
esqueleto abaixo:

x = 1
while x < 11:
# Line of code.
# Line of code.
# Line of code.

Verifique

Exercício 3

Crie um programa com um loop for e uma declaração break . O programa deve iterar sobre
os caracteres de um endereço de e-mail, sair do loop quando chegar ao símbolo @ , e imprimir
a parte antes de @ numa linha. Use o esqueleto abaixo:

for ch in "john.smith@pythoninstitute.org":
if ch == "@":
# Line of code.
# Line of code.

Verifique

Exercício 4

Crie um programa com um loop for e uma declaração continue . O programa deve iterar
sobre uma string de dígitos, substituir cada 0 com x e imprimir a string modificada no ecrã.
Use o esqueleto abaixo:

for digit in "0165031806510":


if digit == "0":
# Line of code.
# Line of code.
# Line of code.

Verifique
Exercício 5

Qual é o output do seguinte código?

n = 3

while n > 0:
print(n + 1)
n -= 1
else:
print(n)

Verifique

Exercício 6

Qual é o output do seguinte código?

n = range(4)

for num in n:
print(num - 1)
else:
print(num)

Verifique

Exercício 7

Qual é o output do seguinte código?

for i in range(0, 6, 3):


print(i)

Verifique

Lógica de computador
Já reparou que as condições que utilizámos até agora têm sido muito simples, para não dizer
bastante primitivas? As condições que utilizamos na vida real são muito mais complexas.
Vejamos esta frase:

Se tivermos algum tempo livre, e o tempo estiver bom, vamos dar um passeio.
Utilizámos a conjunção and , o que significa que ir dar um passeio depende do cumprimento
simultâneo destas duas condições. Na linguagem da lógica, tal ligação de condições é chamada
uma conjunção. E agora outro exemplo:

Se estiveres no centro comercial ou eu estiver no centro comercial, um de nós vai comprar um


presente para a mãe.

A aparência da palavra or significa que a compra depende de pelo menos uma destas
condições. Em lógica, tal composto é chamado uma disjunção.

É evidente que o Python deve ter operadores para construir conjunções e disjunções. Sem eles,
o poder expressivo da linguagem ficaria substancialmente enfraquecido. Eles são
chamados operadores lógicos.

and
Um operador de conjunção lógica em Python é a palavra and. É um operador binário com
uma prioridade que é inferior à expressa pelos operadores de comparação. Permite-nos
codificar condições complexas sem o uso de parêntesis como esta:

counter > 0 and value == 100

O resultado fornecido pelo operador and pode ser determinado com base na tabela da
verdade.

Se considerarmos a conjunção de A e B , o conjunto de valores possíveis de argumentos e


valores correspondentes da conjunção parece ser o seguinte:

Argumento A Argumento B A e B
False False False
False True False
True False False
True True True

or
Um operador de disjunção é a palavra or . É um operador binário com uma prioridade
inferior a and ( assim como + comparado com * ). A sua tabela de verdade é a seguinte:

Argumento A Argumento B A ou B
False False False
False True True
True False True
True True True

not
Além disso, há outro operador que pode ser aplicado para construir condições. É um operador
unário que executa uma negação lógica. O seu funcionamento é simples: transforma a
verdade em falsidade e a falsidade em verdade.

Este operador é escrito como a palavra not , e a sua prioridade é muito alta: a mesma que o
unário + e - . A sua tabela de verdade é simples:

Argumento not Argumento


False True
True False

Expressões lógicas
Vamos criar uma variável chamada var e atribuir 1 a ela. As seguintes condições
são equivalentes em pares:

# Example 1:
print(var > 0)
print(not (var <= 0))

# Example 2:
print(var != 0)
print(not (var == 0))

Pode estar familiarizado com as leis de De Morgan. Dizem que:

A negação de uma conjunção é a disjunção das negações.

A negação de uma disjunção é a conjunção das negações.

Vamos escrever a mesma coisa usando Python:


not (p and q) == (not p) or (not q)
not (p or q) == (not p) and (not q)

Note-se como os parêntesis foram utilizados para codificar as expressões - colocámo-los lá


para melhorar a legibilidade.

Devemos acrescentar que nenhum destes operadores de dois argumentos pode ser utilizado
sob a forma abreviada conhecida como op= . Vale a pena recordar esta exceção.

Valores lógicos vs. bits únicos


Os operadores lógicos tomam os seus argumentos como um todo, independentemente da
quantidade de bits que contenham. Os operadores só estão conscientes do valor: zero (quando
todos os bits são redefinidos) significa False ; não zero (quando pelo menos um bit está
definido) significa True .

O resultado das suas operações é um destes valores: False ou True . Isto significa que este
snippet irá atribuir o valor True à variável j se i não for zero; caso contrário, será False .

i = 1
j = not not i

Operadores bitwise
No entanto, existem quatro operadores que lhe permitem manipular bits únicos de dados.
São chamados operadores bitwise.

Abrangem todas as operações que mencionámos anteriormente no contexto lógico, e um


operador adicional. Este é o operador xor (como em exclusivo ou), e é denotado
como ^ (acento circunflexo).

Aqui estão todos eles:

• & (e comercial) - conjunção bitwise;


• | (barra) - disjunção bitwise;
• ~ (til) - negação bitwise;
• ^ (acento circunflexo) - bitwise exclusive ou (xor).

Operações bitwise ( & , | , e ^ )


Argumento A Argumento B A & B A | B A ^ B
0 0 0 0 0
0 1 0 1 1
1 0 0 1 1
1 1 1 1 0
Operações bitwise (~)
Argumento ~ Argumento
0 1
1 0

Vamos facilitar as coisas:

• & requer exatamente dois 1 para fornecer 1 como resultado;


• | requer pelo menos um 1 para fornecer 1 como resultado;
• ^ requer exatamente um 1 para fornecer 1 como resultado.

Acrescentemos uma observação importante: os argumentos destes operadores devem ser


inteiros; não devemos utilizar floats aqui.

A diferença no funcionamento dos operadores lógicos e de bit é importante: os operadores


lógicos não penetram no nível de bits do seu argumento. Eles só estão interessados no
valor inteiro final.

Os operadores bitwise são mais rigorosos: lidam com cada bit separadamente. Se
assumirmos que a variável inteira ocupa 64 bits (o que é comum nos sistemas informáticos
modernos), podemos imaginar a operação bitwise como uma avaliação de 64 vezes do
operador lógico para cada par de bits dos argumentos. Esta analogia é obviamente imperfeita,
pois no mundo real todas estas 64 operações são realizadas ao mesmo tempo
(simultaneamente).

Operações lógicas versus bit: continuação


Vamos agora mostrar-lhe um exemplo da diferença de funcionamento entre as operações
lógicas e as operações de bit. Vamos assumir que as seguintes atribuições foram realizadas:

i = 15
j = 22

Se assumirmos que os números inteiros são armazenados com 32 bits, a imagem bitwise das
duas variáveis será a seguinte:

i: 00000000000000000000000000001111
j: 00000000000000000000000000010110

A atribuição é dada:
log = i and j

Estamos a lidar aqui com uma conjunção lógica. Vamos traçar o curso dos cálculos. Ambas as
variáveis i e j não são zeros, por isso serão consideradas para representar True .
Consultando a tabela da verdade para o operador and , podemos ver que o resultado
será True . Nenhuma outra operação é realizada.

log: True

Agora a operação bitwise - aqui está ela:

bit = i & j

O operador & operará com cada par de bits correspondentes separadamente, produzindo os
valores dos bits relevantes do resultado. Portanto, o resultado será o seguinte:

I 00000000000000000000000000001111
J 00000000000000000000000000010110
bit = i & j 00000000000000000000000000000110

Estes bits correspondem ao valor inteiro de seis.

Vejamos agora os operadores de negação. Primeiro, o lógico:

logneg = not i

A variável logneg será definida como False - nada mais precisa de ser feito.

A negação bitwise é assim:

bitneg = ~i
Pode ser um pouco surpreendente: o valor da variável bitneg é -16 . Isto pode parecer
estranho, mas não é de todo. Se desejar saber mais, deve verificar o sistema de numeração
binária e as regras que regem os números complementares de dois.

I 00000000000000000000000000001111
bitneg = ~i 11111111111111111111111111110000

Cada um destes operadores de dois argumentos pode ser utilizado de forma abreviada. Estes
são os exemplos das suas notações equivalentes:

x = x & y x &= y
x = x | y x |= y
x = x ^ y x ^= y

Como lidamos com bits individuais?


Vamos agora mostrar-lhe aquilo para que pode utilizar os operadores bitwise. Imagine que é
um programador obrigado a escrever uma parte importante de um sistema operativo. Foi
informado de que tem permissão para usar uma variável atribuída da seguinte maneira:

flag_register = 0x1234

A variável armazena as informações sobre vários aspectos da operação do sistema. Cada bit
da variável armazena um valor yes/no. Também lhe foi dito que apenas um destes bits é seu
- o terceiro (lembre-se que os bits são numerados a partir do zero, e o bit número zero é o mais
baixo, enquanto o mais alto é o número 31). Os bits restantes não podem ser alterados, porque
se destinam a armazenar outros dados. Aqui está o seu bit marcado pela letra x :

flag_register = 0000000000000000000000000000x000

Pode ser confrontado com as seguintes tarefas:

1. Verifique o estado do seu bit - quer descobrir o valor do seu bit; comparar a variável
inteira com zero não fará nada, porque os bits restantes podem ter valores completamente
imprevisíveis, mas pode usar a seguinte propriedade de conjunção:

x & 1 = x
x & 0 = 0

Se aplicar a & operação à flag_register variável juntamente com a seguinte imagem de bit:
00000000000000000000000000001000

(observe o 1 na posição do seu bit) como resultado, obtém uma das seguintes strings de bit:

• 00000000000000000000000000001000 se o seu bit foi definido para 1


• 00000000000000000000000000000000 se o seu bit foi redefinido para 0

Tal sequência de zeros e uns, cuja tarefa é agarrar o valor ou alterar os bits selecionados, é
chamada de bit mask.

Vamos criar uma bit mask para detetar o estado do seu bit. Deve apontar para o terceiro bit.
Esse bit tem o peso de 23 = 8 . Uma mask adequada poderia ser criada através da seguinte
declaração:

the_mask = 8

Também pode fazer uma sequência de instruções dependendo do estado do seu bit i aqui está:

if flag_register & the_mask:


# My bit is set.
else:
# My bit is reset.

2. Redefina o seu bit - atribua um zero ao bit enquanto todos os outros bits devem
permanecer inalterados; utilizemos a mesma propriedade de conjunção como antes, mas
utilizemos uma mask ligeiramente diferente - exatamente como em baixo:

11111111111111111111111111110111

Observe que a mask foi criada como resultado da negação de todos os bits
de the_mask variável. Redefinir o bit é simples, e parece-se com isto (escolha o que mais
gostar):

flag_register = flag_register & ~the_mask


flag_register &= ~the_mask
3. Defina o seu bit - atribua um 1 ao seu bit, enquanto todos os bits restantes devem
permanecer inalterados; use a seguinte propriedade de disjunção:

x | 1 = 1
x | 0 = x

Agora está pronto para definir o seu bit com uma das seguintes instruções:

flag_register = flag_register | the_mask


flag_register |= the_mask

4. Negue o seu bit - substitua um 1 com um 0 e um 0 com um 1 . Pode utilizar uma


propriedade interessante do xor operador:

x ^ 1 = ~x
x ^ 0 = x

e negue o seu bit com as seguintes instruções:

flag_register = flag_register ^ the_mask


flag_register ^= the_mask

Shifting binário à esquerda e shifting binário à


direita
O Python oferece mais uma operação relacionada a bits individuais: shifting (deslocamento).
Isto é aplicado apenas a valores inteiros, e não se deve utilizar floats como argumentos.

Você já aplica esta operação com alguma frequência, e bastante inconscientemente. De que
forma multiplica qualquer número por dez? Dê uma vista de olhos:

12345 × 10 = 123450

Como se pode ver, multiplicar por dez é, de facto, um shifting de todos os dígitos para a
esquerda, preenchendo a lacuna resultante com zero.

Divisão por dez? Dê uma vista de olhos:


12340 ÷ 10 = 1234

Dividir por dez não é mais do que um shifting dos dígitos para a direita

O mesmo tipo de operação é realizado pelo computador, mas com uma diferença: como dois é
a base para números binários (não 10), o shifting de um valor um bit para a esquerda
corresponde assim a multiplicá-lo por dois; respetivamente, o shifting um bit para a
direita é o mesmo que dividí-lo por dois (repare que o bit mais à direita é perdido).

Os operadores shift em Python são um par de dígrafos: << e >> , sugerindo claramente em
que direção a mudança irá ocorrer.

value << bits


value >> bits

O argumento à esquerda destes operadores é um valor inteiro cujos bits são deslocados.
O argumento à direita determina o tamanho do shifting.

Isto demonstra que esta operação não é certamente comutativa.

A prioridade destes operadores é muito alta. Vê-los-á na tabela de prioridades atualizada, que
lhe mostraremos no final desta secção.

Dê uma vista de olhos nas mudanças na janela do editor.

A invocação print() final produz o seguinte output:

17 68 8

output

Nota:

• 17 >> 1 → 17 // 2 (17 divido por baixo por 2 à potência de 1) → 8 (shifting para


a direita por um bit é o mesmo que a divisão inteira por dois)
• 17 << 2 → 17 * 4 17 multiplicado por 2 à potência de 2) → 68 (shifting para a
esquerda por dois bits é o mesmo que a multiplicação de inteiros por quatro)

E aqui está a tabela de prioridades atualizada, contendo todos os operadores introduzidos


até agora:
Prioridade Operador
1 ~, +, - Unário
2 **
3 * , / , // , %
4 +, - binário
5 << , >>
6 < , <= , > , >=
7 == , !=
8 &
9 |
10 = , += , -= , *= , /= , %= , &= , ^= , |= , >>= , <<=

Key takeaways

1. O Python suporta os seguintes operadores lógicos:

• and → se ambos os operandos forem verdadeiros, a condição é verdadeira, por


exemplo, (True and True) é True ,
• or → se algum dos operandos for verdadeiro, a condição é verdadeira, por
exemplo, (True or False) é True ,
• not → retorna falso se o resultado for verdadeiro, e retorna verdadeiro se o resultado
for falso, por exemplo, not True é False .

2. Pode utilizar operadores bitwise para manipular bits únicos de dados. Os seguintes dados de
amostra:

• x = 15 , que é 0000 1111 em binário,


• y = 16 , que é 0001 0000 em binário.

serão utilizados para ilustrar o significado de operadores bitwise em Python. Analise os


exemplos em baixo:

• & faz um bitwise and, por exemplo, x & y = 0 , que é 0000 0000 em binário,
• | faz um bitwise ou, por exemplo, x | y = 31 , que é 0001 1111 em binário,
• ˜ faz um bitwise não, por exemplo, ˜ x = 240 *, que é 1111 0000 em binário,
• ^ faz um bitwise xor, por exemplo, x ^ y = 31 , que é 0001 1111 em binário,
• >> faz um bitwise right shift, por exemplo, y >> 1 = 8 , que é 0000 1000 em
binário,
• << faz um bitwise left shift, por exemplo, y << 3 = , que é 1000 0000 em binário,

* -16 (decimal do complemento assinado de 2) — leia mais sobre a Two's


complement operation (operação de complemento de dois).

Exercício 1

Qual é o output do seguinte snippet?

x = 1
y = 0

z = ((x == y) and (x == y)) or not(x == y)


print(not(z))

Verifique

Exercício 2

Qual é o output do seguinte snippet?

x = 4
y = 1

a = x & y
b = x | y
c = ~x # tricky!
d = x ^ 5
e = x >> 2
f = x << 2

print(a, b, c, d, e, f)

Verifique

Porque precisamos de listas?


Pode acontecer que tenha de ler, armazenar, processar e, finalmente, imprimir dezenas, talvez
centenas, talvez até milhares de números. E então, o quê? É necessário criar uma variável em
separado para cada valor? É necessário passar várias horas a escrever declarações como as
abaixo?

var1 = int(input())
var2 = int(input())
var3 = int(input())
var4 = int(input())
var5 = int(input())
var6 = int(input())
:
:

Se pensa que esta não é uma tarefa complicada, então pegue num pedaço de papel e escreva
um programa que:

• leia cinco números,


• que os imprima por ordem do mais pequeno ao maior (este tipo de processamento
chama-se triagem).

Deve chegar à conclusão de que não tem sequer papel suficiente para completar a tarefa.

Até agora, aprendeu a declarar variáveis que são capazes de armazenar exatamente um
determinado valor de cada vez. Tais variáveis são por vezes chamadas escalares, por analogia
com a matemática. Todas as variáveis que utilizou até agora são, na verdade, escalares.

Pense no quão conveniente seria declarar uma variável que pudesse armazenar mais do que
um valor. Por exemplo, cem, ou mil, ou até dez mil. Seria ainda uma e a mesma variável, mas
muito ampla e espaçosa. Parece apelativa? Talvez, mas como lidaria com um recipiente cheio
de valores diferentes? Como escolheria apenas aquele de que necessita?

E se pudesse simplesmente numerá-los? E depois dizer: dá-me o valor número 2; atribui o valor
número 15; aumenta o valor número 10000.

Vamos mostrar-lhe como declarar tais variáveis multi-valores. Vamos fazer isto com o
exemplo que acabámos de sugerir. Vamos escrever um programa que ordena uma
sequência de números. Não seremos particularmente ambiciosos - vamos assumir que
existem exatamente cinco números.

Vamos criar uma variável chamada numbers ; é atribuída não apenas com um número, mas é
preenchida com uma lista constituída por cinco valores (nota: a lista começa com um
parêntesis reto aberto e termina com um parêntesis reto fechado; o espaço entre os
parêntesis é preenchido com cinco números separados por vírgulas).

numbers = [10, 5, 7, 2, 1]
Digamos a mesma coisa usando terminologia adequada: numbers é uma lista constituída
por cinco valores, todos eles números. Podemos também dizer que esta declaração cria uma
lista de comprimento igual a cinco (visto existir cinco elementos no seu interior).

Os elementos dentro de uma lista podem ter tipos diferentes. Alguns deles podem ser
inteiros, outros floats, e outros ainda podem ser listas.

O Python adotou uma convenção, afirmando que os elementos numa lista são sempre
numerados a partir do zero. Isto significa que o artigo armazenado no início da lista terá o
número zero. Uma vez que existem cinco elementos na nossa lista, ao último deles é atribuído
o número quatro. Não esqueça isto.

Rapidamente se acostumará a isto, e tornar-se-á uma segunda natureza.

Antes de avançarmos na nossa discussão, temos de referir o seguinte: a nossa lista é uma
coleção de elementos, mas cada elemento é um escalar.

Indexar listas
Como se altera o valor de um elemento escolhido na lista?

Vamos atribuir um novo valor de 111 ao primeiro elemento na lista. Fazemo-lo


assim:

numbers = [10, 5, 7, 2, 1]

print("Original list content:", numbers) # Printing original list


content.

numbers[0] = 111

print("New list content: ", numbers) # Current list content.

E agora queremos que o valor do quinto elemento seja copiado para o segundo
elemento - consegue adivinhar como o fazer?

numbers = [10, 5, 7, 2, 1]

print("Original list content:", numbers) # Printing original list


content.

numbers[0] = 111

print("\nPrevious list content:", numbers) # Printing previous


list content.
numbers[1] = numbers[4] # Copying value of the fifth element to
the second.

print("New list content:", numbers) # Printing current list


content.

O valor dentro dos parêntesis que seleciona um elemento da lista é chamado


um index, enquanto a operação de selecionar um elemento da lista é conhecida
como indexing (indexação).

Vamos utilizar a função print() para imprimir o conteúdo da lista cada vez que
fazemos as alterações. Isto ajudar-nos-á a seguir cada passo com mais cuidado e a ver
o que se passa após uma determinada modificação da lista.

Nota: todos os índices usados até agora são literais. Os seus valores são fixados em
runtime, mas qualquer expressão também pode ser o index. Isto oferece muitas
possibilidades.

Aceder ao conteúdo da lista


Cada um dos elementos da lista pode ser acedido separadamente. Por exemplo, pode
ser impresso:

print(numbers[0]) # Accessing the list's first element.

Assumindo que todas as operações anteriores tenham sido concluídas com sucesso, o
snippet enviará 111 para a consola.

Como pode ver no editor, a lista também pode ser impressa como um todo - tal como
aqui:

print(numbers) # Printing the whole list.

Como provavelmente já notou antes, o Python decora o output de uma forma que
sugere que todos os valores apresentados formam uma lista. O output do exemplo
acima é o seguinte:
[111, 1, 7, 2, 1]

output

O método len() .
O comprimento de uma lista pode variar durante a execução. Novos elementos
podem ser acrescentados à lista, enquanto outros podem ser retirados da mesma.
Isto significa que a lista é uma entidade muito dinâmica.

Se quiser verificar o comprimento atual da lista, pode usar uma função


chamada len() (o seu nome vem de length (comprimento)).

A função toma o nome da lista como argumento, e devolve o número de


elementos atualmente armazenados dentro da lista (por outras palavras - o
comprimento da lista).

Veja a última linha de código no editor, execute o programa e verifique que valor irá
imprimir para a consola. Consegue adivinhar?

Remover elementos de uma lista


Qualquer elemento da lista pode ser removido a qualquer momento - isto é feito com
uma instrução chamada del (delete). Nota: é uma instrução, não uma função.

É preciso apontar o elemento a ser removido - desaparecerá da lista, e o comprimento


da lista será reduzido em um.

Olhe para o snippet abaixo. Consegue adivinhar que output irá produzir? Execute o
programa no editor e verifique.

del numbers[1]
print(len(numbers))
print(numbers)
Não se pode aceder a um elemento que não existe - não se pode obter o seu valor
nem atribuir-lhe um valor. Ambas estas instruções irão agora causar erros de runtime:

print(numbers[4])
numbers[4] = 1

Adicione o snippet acima após a última linha de código no editor, execute o programa
e verifique o que acontece.

Nota: retirámos um dos elementos da lista - agora só há quatro elementos na lista.


Isto significa que o elemento número quatro não existe.

Índices negativos são legais


Pode parecer estranho, mas os índices negativos são legais, e podem ser muito úteis.
Um elemento com um index igual a -1 é o último na lista.

print(numbers[-1])

O snippet de exemplo terá como output 1 . Execute o programa e verifique.

Da mesma forma, o elemento com um index igual a -2 é o penúltimo na lista.

print(numbers[-2])

O snippet de exemplo terá como output 2 .

O último elemento acessível da nossa lista é numbers[-4] (o primeiro) - não tente ir


mais longe!

LAB

Tempo estimado
5 minutos
Nível de dificuldade
Muito fácil

Objetivos
Familiarizar o aluno a:

• utilizar instruções básicas relacionadas com listas;


• criar e modificar listas.

Cenário
Houve uma vez um chapéu. O chapéu não continha nenhum coelho, mas uma lista de
cinco números: 1 , 2 , 3 , 4 , e 5 .

A sua tarefa é:

• escrever uma linha de código que peça ao utilizador para substituir o número
médio na lista por um número inteiro introduzido pelo utilizador (Passo 1)
• escrever uma linha de código que remova o último elemento da lista (Passo 2)
• escrever uma linha de código que imprima o comprimento da lista existente
(Passo 3).

Pronto para este desafio?

Funções vs. métodos


Um método é um tipo específico de função - comporta-se como uma função e parece uma
função, mas difere na forma como atua, e no seu estilo de invocação.

Uma função não pertence a nenhum dado - recebe dados, pode criar novos dados e
(geralmente) produz um resultado.
Um método faz todas estas coisas, mas também é capaz de alterar o estado de uma entidade
selecionada.

Um método é propriedade dos dados para os quais trabalha, enquanto uma função é
propriedade de todo o código.

Isto também significa que a invocação de um método requer alguma especificação dos dados a
partir dos quais o método é invocado.

Pode parecer intrigante aqui, mas lidaremos com isso em profundidade quando nos
aprofundarmos na programação orientada ao objeto.

Em geral, uma invocação de função típica pode parecer-se com isto:

result = function(arg)

A função toma um argumento, faz algo, e devolve um resultado.

Um método típico de invocação é geralmente semelhante a este:

result = data.method(arg)

Nota: o nome do método é precedido do nome dos dados que possuem o método. Em seguida,
adiciona-se um ponto, seguido do nome do método, e um par de parêntesis que encerra os
argumentos.

O método comportar-se-á como uma função, mas pode fazer algo mais - pode alterar o estado
interno dos dados a partir dos quais foi invocado.

Pode perguntar: porque estamos a falar de métodos e não de listas?

Esta é uma questão essencial neste momento, pois vamos mostrar-lhe como adicionar novos
elementos a uma lista existente. Isto pode ser feito com métodos pertencentes a todas as listas,
e não por funções.
Adicionar elementos a uma
lista: append() e insert()
Um novo elemento pode ser colado no fim da lista existente:

list.append(value)

Tal operação é realizada por um método chamado append() . Toma o valor do seu
argumento e coloca-o no final da lista que possui o método.

O comprimento da lista aumenta então em um.

O método insert() é um pouco mais inteligente - pode acrescentar um novo


elemento em qualquer lugar da lista, e não apenas no final.

list.insert(location, value)

São necessários dois argumentos:

• o primeiro mostra a localização necessária do elemento a ser inserido; nota:


todos os elementos existentes que ocupam locais à direita do novo elemento
(incluindo o que se encontra na posição indicada) são deslocados para a
direita, a fim de criar espaço para o novo elemento;
• o segundo é o elemento a ser inserido.
Veja o código no editor. Veja como utilizamos os append() e insert() métodos.
Preste atenção ao que acontece após a utilização insert(): o primeiro elemento é
agora o segundo, o segundo o terceiro, e assim por diante.

Adicione o seguinte snippet após a última linha de código no editor:

numbers.insert(1, 333)

Imprima o conteúdo da lista final para o ecrã e veja o que acontece. O snippet acima
do snippet insere 333 na lista, tornando-o no segundo elemento. O anterior segundo
elemento torna-se o terceiro, o terceiro o quarto, e assim por diante.
Adicionar elementos a uma lista: continuação
Pode iniciar a vida de uma lista tornando-a vazia (isto é feito com um par de
parêntesis retos vazio) e depois adicionando-lhe novos elementos conforme
necessário.

Veja o snippet no editor. Tente adivinhar o seu output após a execução do loop for .
Execute o programa para verificar se estava certo.

Será uma sequência de números inteiros consecutivos a partir de 1 (depois adiciona-


se um a todos os valores anexados) até 5 .

Modificámos um pouco o snippet:

my_list = [] # Creating an empty list.

for i in range(5):
my_list.insert(0, i + 1)

print(my_list)

O que acontecerá agora? Execute o programa e verifique se desta vez também estava
certo.

Deve obter a mesma sequência, mas em ordem inversa (este é o mérito de usar o
método insert() ).

Utilização de listas
O loop for tem uma variante muito especial que pode processar listas muito
eficazmente - vejamos isso.

Vamos supor que deseja calcular a soma de todos os valores armazenados na


lista my_list .

É necessária uma variável cuja soma será armazenada e à qual será inicialmente
atribuído um valor de 0 - o seu nome será total . (Nota: não vamos nomeá-
la sum visto o Python usar o mesmo nome para uma das suas funções internas
- sum() . Utilizar o mesmo nome seria geralmente considerado uma má prática).
Em seguida, acrescenta-lhe todos os elementos da lista utilizando o loop for . Veja o
snippet no editor.

Vamos comentar este exemplo:


• à lista é atribuída uma sequência de cinco valores inteiros;
• a variável i toma os valores 0 , 1 , 2 , 3 , e 4 , e depois indexa a lista,
selecionando os elementos seguintes: o primeiro, o segundo, o terceiro, o
quarto e o quinto;
• cada um destes elementos é adicionado em conjunto pelo operador += à
variável total , dando o resultado final no fim do loop;
• observe a forma como a função len() foi utilizada - torna o código
independente de quaisquer possíveis alterações no conteúdo da lista.

A segunda face do loop for .


Mas o loop for pode fazer muito mais. Pode ocultar todas as ações ligadas à
indexação da lista, e entregar todos os elementos da lista de uma forma prática.

Este snippet modificado mostra como isto funciona:

my_list = [10, 1, 8, 3, 5]
total = 0

for i in my_list:
total += i

print(total)

O que acontece aqui?

• a instrução for especifica a variável usada para navegar na lista ( i aqui)


seguida pela keyword in e pelo nome da lista que está a ser processada
( my_list aqui)
• à variável i são atribuídos os valores de todos os elementos da lista
subsequente, e o processo ocorre tantas vezes quantos os elementos da lista;
• isto significa que se utiliza a variável i como uma cópia dos valores dos
elementos, e não se precisa de utilizar índices;
• a função len() também não é necessária aqui.
Listas em ação
Deixemos as listas de lado por um breve momento e vejamos uma questão intrigante.

Imagine que precisa de reorganizar os elementos de uma lista, ou seja, inverter a


ordem dos elementos: o primeiro e o quinto, bem como o segundo e o quarto
elementos serão trocados. O terceiro permanecerá intocado.

Pergunta: como se pode trocar os valores de duas variáveis?

Veja o snippet:

variable_1 = 1
variable_2 = 2

variable_2 = variable_1
variable_1 = variable_2

Se fizer algo como isto, perderá o valor previamente armazenado em variable_2 .


Alterar a ordem das atribuições não ajudará. É necessária uma terceira variável que
sirva como armazenamento auxiliar.

É assim que se pode fazer:

variable_1 = 1
variable_2 = 2
auxiliary = variable_1
variable_1 = variable_2
variable_2 = auxiliary

O Python oferece uma forma mais conveniente de fazer a troca - veja:

variable_1 = 1
variable_2 = 2

variable_1, variable_2 = variable_2, variable_1

Claro, eficaz e elegante - não é?

Listas em ação
Agora pode facilmente trocar os elementos da lista para inverter a sua ordem:

my_list = [10, 1, 8, 3, 5]

my_list[0], my_list[4] = my_list[4], my_list[0]


my_list[1], my_list[3] = my_list[3], my_list[1]

print(my_list)

Execute o snippet. O seu output deve ter este aspeto:

[5, 3, 8, 1, 10]

output

Fica bem com cinco elementos.

Será ainda aceitável com uma lista contendo 100 elementos? Não, não será.
Pode utilizar o loop for para fazer a mesma coisa automaticamente,
independentemente do comprimento da lista? Sim, pode.

Foi assim que o fizemos:

my_list = [10, 1, 8, 3, 5]
length = len(my_list)

for i in range(length // 2):


my_list[i], my_list[length - i - 1] = my_list[length - i - 1],
my_list[i]

print(my_list)

Nota:

• nós atribuímos a variável length com o comprimento da lista atual (isto torna
o nosso código um pouco mais claro e mais curto)
• lançámos o loop for para correr através do seu corpo length // 2 vezes
(isto funciona bem para listas com comprimentos pares e ímpares, porque
quando a lista contém um número ímpar de elementos, o do meio permanece
intocado)
• trocamos o i-ésimo elemento (desde o início da lista) com o que tem um index
igual a (length - i - 1) (do final da lista); no nosso exemplo, para i igual
a 0 o ramo (lenght - i - 1) dá 4 ; para i igual a 1 , dá 3 - Isto é exatamente
o que precisávamos.

As listas são extremamente úteis, e irá encontrá-las com muita frequência.

LAB

Tempo estimado
10-15 minutos

Nível de dificuldade
Fácil

Objetivos
Familiarizar o aluno a:

• a criação e modificação de listas simples;


• utilizar métodos para modificar listas.

Cenário
Os Beatles foram um dos grupos musicais mais populares dos anos 1960, e a banda
mais best-seller da história. Algumas pessoas consideram-nas o ato mais influente da
era do rock. De facto, foram incluídos na compilação da revista Time das 100 pessoas
mais influentes do século XX.

A banda passou por muitas mudanças de formação, culminando em 1962 com o line-
up de John Lennon, Paul McCartney, George Harrison, e Richard Starkey (mais
conhecido como Ringo Starr).

Escreva um programa que reflita estas mudanças e lhe permita praticar com o
conceito de listas. A sua tarefa é:

• passo 1: criar uma lista vazia com o nome beatles ;


• passo 2: utilizar o método append() para adicionar os seguintes membros da
banda à lista: John Lennon , Paul McCartney , e George Harrison ;
• passo 3: utilizar o loop for e o método append() para solicitar ao utilizador
que adicione os seguintes membros da banda à lista: Stu Sutcliffe , e Pete
Best ;
• passo 4: utilizar a instrução del para remover Stu Sutcliffe e Pete Best da
lista;
• passo 5: utilizar o método insert() para adicionar Ringo Starr ao início da
lista.

A propósito, é fã dos Beatles? (Os Beatles são uma das bandas favoritas de Greg. Mas
calma...quem é o Greg....?)
Key takeaways

1. A lista é um tipo de dados em Python usada para armazenar vários objetos. É


uma coleção ordenada e mutável de ítens separados por vírgulas, entre parêntesis retos, por
exemplo:

my_list = [1, None, True, "I am a string", 256, 0]


2. As listas podem ser indexadas e atualizadas, por exemplo:

my_list = [1, None, True, 'I am a string', 256, 0]

print(my_list[3]) # outputs: I am a string

print(my_list[-1]) # outputs: 0

my_list[1] = '?'

print(my_list) # outputs: [1, '?', True, 'I am a string', 256, 0]

my_list.insert(0, "first")

my_list.append("last")

print(my_list) # outputs: ['first', 1, '?', True, 'I am a string',


256, 0, 'last']

3. As listas podem ser nested, por exemplo:

my_list = [1, 'a', ["list", 64, [0, 1], False]]

Aprenderá mais sobre o nesting no módulo 3.1.7 - por enquanto, só queremos que esteja ciente
de que algo como isto também é possível.

4. Os elementos da lista e as listas podem ser excluídos, por exemplo:

my_list = [1, 2, 3, 4]

del my_list[2]

print(my_list) # outputs: [1, 2, 4]

del my_list # deletes the whole list


Novamente, aprenderá mais sobre isto no módulo 3.1.6 - não se preocupe. Por enquanto, basta
tentar experimentar o código acima e verificar como a sua alteração afeta o output.

5. As listas podem ser iteradas através da utilização do loop for , por exemplo:

my_list = ["white", "purple", "blue", "yellow", "green"]

for color in my_list:

print(color)

6. A função len() pode ser usada para verificar o comprimento da lista, por exemplo:

my_list = ["white", "purple", "blue", "yellow", "green"]

print(len(my_list)) # outputs 5

del my_list[2]

print(len(my_list)) # outputs 4

7. Uma invocação de função típica parece-se com a seguinte: result = function(arg) ,


enquanto uma invocação de método típica parece-se com isto: result =
data.method(arg) .

Exercício 1

Qual é o output do seguinte snippet?

lst = [1, 2, 3, 4, 5]

lst.insert(1, 6)

del lst[0]

lst.append(1)
print(lst)

Verifique

Exercício 2

Qual é o output do seguinte snippet?

lst = [1, 2, 3, 4, 5]

lst_2 = []

add = 0

for number in lst:

add += number

lst_2.append(add)

print(lst_2)

Verifique

Exercício 3

O que acontece quando executa o seguinte snippet?

lst = []

del lst

print(lst)

Verifique

Exercício 4

Qual é o output do seguinte snippet?


lst = [1, [2, 3], 4]

print(lst[1])

print(len(lst))

Verifique

O bubble sort
Agora que pode efetivamente fazer malabarismos com os elementos das listas, é tempo de
aprender a ordená-los. Muitos algoritmos de ordenação foram inventados até agora, que
diferem muito na velocidade, bem como na complexidade. Vamos mostrar-lhe um algoritmo
muito simples, fácil de compreender, mas infelizmente também não muito eficiente. É utilizado
muito raramente, e certamente não para listas grandes e extensas.

Digamos que uma lista pode ser ordenada de duas maneiras:

• crescente (ou mais precisamente - não decrescente) - se em cada par de elementos


adjacentes, o primeiro elemento não for maior do que o segundo;
• decrescente (ou mais precisamente - não crescente) - se em cada par de elementos
adjacentes, o primeiro elemento não for inferior ao segundo.

Nas secções seguintes, ordenaremos a lista por ordem crescente, de modo a que os números
sejam ordenados do mais pequeno para o maior.

Aqui está a lista:

8 10 6 2 4

Tentaremos usar a seguinte abordagem: tomaremos o primeiro e o segundo elementos e


compará-los-emos; se determinarmos que estão na ordem errada (ou seja, o primeiro é maior
que o segundo), trocá-los-emos; se a sua ordem for válida, não faremos nada. Um olhar sobre a
nossa lista confirma esta última - os elementos 01 e 02 estão na ordem correta, como em 8 <
10 .

Agora olhe para o segundo e o terceiro elementos. Estão nas posições erradas. Temos de os
trocar:

8 6 10 2 4

Vamos mais longe, e olhemos para o terceiro e quarto elementos. Novamente, não é assim que
deveria ser. Temos de os trocar:

8 6 2 10 4
Agora verificamos o quarto e o quinto elementos. Sim, eles também estão nas posições erradas.
Outra troca ocorre:

8 6 2 4 10

A primeira passagem pela lista já está terminada. Ainda estamos longe de terminar o nosso
trabalho, mas algo de curioso aconteceu entretanto. O maior elemento, 10 , já foi para o final da
lista. Note-se que este é o lugar desejado para ele. Todos os elementos restantes formam uma
confusão pitoresca, mas este já está no lugar.

Agora, por um momento, tente imaginar a lista de uma forma ligeiramente diferente -
nomeadamente, assim:

10
4
2
6
8

Olhe - 10 está no topo. Poderíamos dizer que flutuou do fundo para a superfície, tal como
a bolha numa taça de champanhe. O método de classificação deriva o seu nome da mesma
observação - chama-se um bubble sort (uma espécie de bolha).

Agora começamos com a segunda passagem através da lista. Olhamos para o primeiro e
segundo elementos - é necessária uma troca:

6 8 2 4 10

Tempo para o segundo e terceiro elementos: temos de os trocar também:

6 2 8 4 10

Agora o terceiro e quarto elementos, e a segunda passagem está terminada, visto 8 já estar no
lugar:
6 2 4 8 10

Começamos a próxima passagem imediatamente. Observe cuidadosamente o primeiro e o


segundo elementos - é necessária outra troca:

2 6 4 8 10

Agora 6 precisa de ser posto no lugar. Trocamos o segundo e o terceiro elementos:

2 4 6 8 10

A lista já está ordenada. Não temos mais nada a fazer. Isto é exatamente o que queremos.

Como pode ver, a essência deste algoritmo é simples: comparamos os elementos adjacentes
e, trocando alguns deles, atingimos o nosso objetivo

Vamos codificar em Python todas as ações realizadas durante uma única passagem através da
lista, e depois vamos considerar quantas passagens realmente precisamos para a realizar.
Ainda não explicámos isto até agora, e faremos isso um pouco mais tarde.

Classificar uma lista


Quantas passagens precisamos para ordenar a lista completa?

Resolvemos esta questão da seguinte forma: introduzimos outra variável; a sua


tarefa é observar se foi feita alguma troca durante a passagem ou não; se não houver
troca, então a lista já está ordenada, e nada mais tem de ser feito. Criamos uma
variável chamada swapped , e atribuímos-lhe um valor de False , para indicar que não
há trocas. Caso contrário, será atribuído True .

my_list = [8, 10, 6, 2, 4] # list to sort

for i in range(len(my_list) - 1): # we need (5 - 1) comparisons


if my_list[i] > my_list[i + 1]: # compare adjacent elements
my_list[i], my_list[i + 1] = my_list[i + 1], my_list[i] #
If we end up here, we have to swap the elements.

Deverá ser capaz de ler e compreender este programa sem quaisquer problemas:

my_list = [8, 10, 6, 2, 4] # list to sort


swapped = True # It's a little fake, we need it to enter the while
loop.

while swapped:
swapped = False # no swaps so far
for i in range(len(my_list) - 1):
if my_list[i] > my_list[i + 1]:
swapped = True # a swap occurred!
my_list[i], my_list[i + 1] = my_list[i + 1], my_list[i]

print(my_list)

Execute o programa e teste-o.

O bubble sort - versão interativa


No editor pode ver um programa completo, enriquecido por uma conversa com o
utilizador, e que permite ao utilizador introduzir e imprimir elementos da lista: O
bubble sort - versão interativa final.

O Python, contudo, tem os seus próprios mecanismos de ordenação. Ninguém precisa


de escrever a sua própria ordenação, uma vez que existe um número suficiente
de ferramentas prontas a usar.

Explicámos-lhe este sistema de ordenação porque é importante aprender a processar


o conteúdo de uma lista, e mostrar-lhe como a ordenação real pode funcionar.

Se quiser que o Python ordene a sua lista, pode fazê-lo desta forma:

my_list = [8, 10, 6, 2, 4]


my_list.sort()
print(my_list)

É tão simples quanto isso.

O output do snippet é o seguinte:

[2, 4, 6, 8, 10]

output
Como pode ver, todas as listas têm um método chamado sort() , que as classifica o
mais rapidamente possível. Já aprendeu alguns dos métodos de lista antes, e vai
aprender mais sobre outros muito em breve.

Key takeaways

1. Pode utilizar a keyword sort() para ordenar elementos de uma lista, por exemplo:

lst = [5, 3, 1, 2, 4]

print(lst)

lst.sort()

print(lst) # outputs: [1, 2, 3, 4, 5]


2. Há também um método de lista chamado reverse() , que pode utilizar para inverter a lista,
por exemplo

lst = [5, 3, 1, 2, 4]

print(lst)

lst.reverse()

print(lst) # outputs: [4, 2, 1, 3, 5]

Exercício 1

Qual é o output do seguinte snippet?

lst = ["D", "F", "A", "Z"]

lst.sort()

print(lst)

Verifique

['A', 'D', 'F', 'Z']

Exercício 2

Qual é o output do seguinte snippet?

a = 3

b = 1

c = 2
lst = [a, c, b]

lst.sort()

print(lst)

Verifique

[1, 2, 3]

Exercício 3

Qual é o output do seguinte snippet?

a = "A"

b = "B"

c = "C"

d = " "

lst = [a, b, c, d]

lst.reverse()

print(lst)

Verifique

[' ', 'C', 'B', 'A']

A vida interna das listas


Agora queremos mostrar-lhe uma característica importante, e muito surpreendente,
das listas, que as distingue fortemente das variáveis comuns.

Queremos que o memorize - pode afetar os seus programas futuros, e causar graves
problemas se esquecido ou negligenciado.
Veja o snippet no editor.

O programa:

• cria uma lista de um elemento chamada list_1 ;


• atribui-o a uma nova lista chamada list_2 ;
• altera o único elemento de list_1 ;
• imprime list_2 .

A parte surpreendente é o facto de que o programa fará o output: [2] , não [1] , que
parece ser a solução óbvia.

As listas (e muitas outras entidades complexas de Python) são armazenadas de formas


diferentes das variáveis ordinárias (escalares).

Pode-se dizer que:

• o nome de uma variável ordinária é o nome do seu conteúdo;


• o nome de uma lista é o nome de um local de memória onde a lista é
armazenada.

Leia estas duas linhas mais uma vez - a diferença é essencial para compreender aquilo
de que vamos falar a seguir.

A atribuição: list_2 = list_1 copia o nome do array, não o seu conteúdo. Com
efeito, os dois nomes ( list_1 e list_2 ) identificam o mesmo local na memória do
computador. Modificar um deles afeta o outro, e vice-versa.

Como se lida com isso?


Slices poderosas
Felizmente, a solução está ao seu alcance - o seu nome é slice.

Uma slice é um elemento da sintaxe Python que lhe permite fazer uma cópia
completamente nova de uma lista ou partes de uma lista.

Na verdade, a slice copia o conteúdo da lista, não o seu nome.

Isto é exatamente o que necessita. Dê uma vista de olhos no snippet em baixo:

list_1 = [1]
list_2 = list_1[:]
list_1[0] = 2
print(list_2)

O seu output é [1] .

Esta parte inconspícua do código descrito como [:] é capaz de produzir uma lista
completamente nova.

Uma das formas mais gerais da slice tem o seguinte aspeto:

my_list[start:end]

Como pode ver, assemelha-se à indexação, mas os dois pontos no interior fazem uma
grande diferença.

Uma slice desta forma faz uma nova lista (alvo), retirando elementos da source
list - os elementos dos índices desde o início até end - 1 .

Nota: não para end mas para end - 1 . Um elemento com um índice igual a end é o
primeiro elemento que não participa no slicing.

É possível utilizar valores negativos tanto para o início como para o fim (tal como na
indexação).

Veja o snippet:

my_list = [10, 8, 6, 4, 2]
new_list = my_list[1:3]
print(new_list)
A new_list lista terá end - start (3 - 1 = 2) elementos - aqueles com índices iguais
a 1 e 2 (mas não 3 ).

O output do snippet é: [8, 6]

Slices - índices negativos


Veja o snippet em baixo:

my_list[start:end]

Para repetir:

• start é o index do primeiro elemento incluído no slice;


• end é o index do primeiro elemento não incluído no slice.

É assim que os índices negativos funcionam com o slice:

my_list = [10, 8, 6, 4, 2]
new_list = my_list[1:-1]
print(new_list)
O output do snippet é:

[8, 6, 4]

output

Se o start especifica um elemento que se encontra mais longe do que o descrito


pelo end (do ponto de vista inicial da lista), o slice estará vazio:

my_list = [10, 8, 6, 4, 2]
new_list = my_list[-1:1]
print(new_list)

O output do snippet é:

[]

output

Slices: continuação
Se omitir o start no seu slice, assume-se que pretende obter um slice começando
pelo elemento com index 0 .

Por outras palavras, o slice desta forma:

my_list[:end]

é um equivalente mais compacto de:

my_list[0:end]

Veja o snippet em baixo:

my_list = [10, 8, 6, 4, 2]
new_list = my_list[:3]
print(new_list)
É por isso que o seu output é: [10, 8, 6] .

Da mesma forma, se omitir o end no seu slice, presume-se que deseja que o slice
termine no elemento com o index len(my_list) .

Por outras palavras, o slice desta forma:

my_list[start:]

é um equivalente mais compacto de:

my_list[start:len(my_list)]

Veja o snippet seguinte:

my_list = [10, 8, 6, 4, 2]
new_list = my_list[3:]
print(new_list)

O seu output é, portanto: [4, 2].

Slices: continuação
Como já dissemos anteriormente, omitindo ambos start e end faz uma cópia de
toda a lista:

my_list = [10, 8, 6, 4, 2]
new_list = my_list[:]
print(new_list)

O output do snippet é: [10, 8, 6, 4, 2] .

A instrução anteriormente descrita del é capaz de apagar mais do que apenas um


elemento de uma lista ao mesmo tempo - também pode apagar slices:
my_list = [10, 8, 6, 4, 2]
del my_list[1:3]
print(my_list)

Nota: neste caso, o slice não produz nenhuma lista nova!

O output do snippet é: [10, 4, 2] .

A eliminação de todos os elementos de uma só vez também é possível:

my_list = [10, 8, 6, 4, 2]
del my_list[:]
print(my_list)

A lista fica vazia e o output é: [] .

A remoção do slice do código muda dramaticamente o seu significado.

Veja:

my_list = [10, 8, 6, 4, 2]
del my_list
print(my_list)

A instrução del eliminará a lista em si, não o seu conteúdo.

A print() invocação da função a partir da última linha do código causará então um


erro de runtime.

Os loops in e not in operadores


O Python oferece dois operadores muito poderosos, capazes de olhar através da
lista a fim de verificar se um valor específico está ou não armazenado dentro da
lista
Estes operadores são:

elem in my_list
elem not in my_list

O primeiro deles ( in ) verifica se um dado elemento (o seu argumento da esquerda)


está atualmente armazenado algures dentro da lista (o argumento da direita) - o
operador devolve True neste caso.

O segundo ( not in ) verifica se um dado elemento (o seu argumento da esquerda)


está ausente numa lista - o operador devolve True neste caso.

Veja o código no editor. O snippet mostra ambos os operadores em ação. Consegue


adivinhar o seu output? Execute o programa para verificar se estava certo.

Listas - alguns programas simples


Agora queremos mostrar-lhe alguns programas simples que utilizam listas.

O primeiro deles tenta encontrar o maior valor na lista. Veja o código no editor.

O conceito é bastante simples - assumimos temporariamente que o primeiro


elemento é o maior, e verificamos a hipótese contra todos os restantes elementos da
lista.

O código fará o output 17 (como esperado).


O código pode ser reescrito para fazer uso da forma recentemente introduzida
do for :

my_list = [17, 3, 11, 5, 1, 9, 7, 15, 13]


largest = my_list[0]

for i in my_list:
if i > largest:
largest = i

print(largest)

O programa acima realiza uma comparação desnecessária, quando o primeiro


elemento é comparado consigo mesmo, mas isto não é de todo um problema.

O código fará o output 17 , também (nada invulgar).

Se precisar de poupar energia do computador, pode utilizar um slice:

my_list = [17, 3, 11, 5, 1, 9, 7, 15, 13]


largest = my_list[0]

for i in my_list[1:]:
if i > largest:
largest = i

print(largest)

A questão é: qual destas duas ações consome mais recursos informáticos - apenas
uma comparação, ou slicing de quase todos os elementos de uma lista?

Listas - alguns programas simples


Agora vamos encontrar a localização de um dado elemento dentro de uma lista:

my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]


to_find = 5
found = False

for i in range(len(my_list)):
found = my_list[i] == to_find
if found:
break

if found:
print("Element found at index", i)
else:
print("absent")

Nota:

• o valor alvo é armazenado na variável to_find ;


• o estado atual da pesquisa é armazenado na variável found ( True / False )
• quando found se torna True , o loop for é saído.

Vamos supor que escolheu os seguintes números na lotaria: 3 , 7 , 11 , 42 , 34 , 49 .

Os números que foram sorteados são: 5 , 11 , 9 , 42 , 3 , 49 .

A questão é: em quantos números é que acertou?

O programa dar-lhe-á a resposta:

drawn = [5, 11, 9, 42, 3, 49]


bets = [3, 7, 11, 42, 34, 49]
hits = 0

for number in bets:


if number in drawn:
hits += 1

print(hits)

Nota:

• a keyword drawn armazena todos os números sorteados;


• a lista bets armazena as suas apostas;
• a variável hits conta os seus êxitos.

O output do programa é: 4 .
LAB

Tempo estimado
10-15 minutos

Nível de dificuldade
Fácil

Objetivos
Familiarizar o aluno a:

• indexação de lista;
• utilizar os operadores in e not in .

Cenário
Imagine uma lista - não muito longa, não muito complicada, apenas uma simples lista
contendo alguns números inteiros. Alguns desses números podem ser repetidos, e
esta é a pista. Não queremos repetições. Queremos que sejam removidas.

A sua tarefa é escrever um programa que remova todas as repetições de números da


lista. O objetivo é ter uma lista na qual todos os números não aparecem mais de uma
vez.

Nota: suponha que a source list está codificada dentro do código - não tem de a
introduzir a partir do teclado. É claro que pode melhorar o código e adicionar uma
parte que pode realizar uma conversa com o utilizador e obter todos os dados a partir
dele.

Dica: encorajamo-lo a criar uma nova lista como área de trabalho temporária - não
precisa de atualizar a lista in situ.

Não fornecemos dados de teste, pois isso seria demasiado fácil. Pode usar o nosso
esqueleto em vez disso.
Key takeaways

1. Se tiver uma lista l1 , então a seguinte tarefa: l2 = l1 não faz uma cópia da lista l1 , mas
faz com que as variáveis l1 e l2 apontem para uma e a mesma lista na memória. Por
exemplo:

vehicles_one = ['car', 'bicycle', 'motor']


print(vehicles_one) # outputs: ['car', 'bicycle', 'motor']

vehicles_two = vehicles_one
del vehicles_one[0] # deletes 'car'
print(vehicles_two) # outputs: ['bicycle', 'motor']

2. Se quiser copiar uma lista ou parte da lista, pode fazê-lo executando slicing:

colors = ['red', 'green', 'orange']

copy_whole_colors = colors[:] # copy the entire list


copy_part_colors = colors[0:2] # copy part of the list

3. Também se podem utilizar índices negativos para executar slices. Por exemplo:

sample_list = ["A", "B", "C", "D", "E"]


new_list = sample_list[2:-1]
print(new_list) # outputs: ['C', 'D']
4. O objeto da exceção start e end parâmetros são opcionais ao executar uma
slice: list[start:end] , por exemplo.:

my_list = [1, 2, 3, 4, 5]
slice_one = my_list[2: ]
slice_two = my_list[ :2]
slice_three = my_list[-2: ]

print(slice_one) # outputs: [3, 4, 5]


print(slice_two) # outputs: [1, 2]
print(slice_three) # outputs: [4, 5]

5. Pode eliminar slices usando a instrução del :

my_list = [1, 2, 3, 4, 5]
del my_list[0:2]
print(my_list) # outputs: [3, 4, 5]

del my_list[:]
print(my_list) # deletes the list content, outputs: []

6. Pode testar se alguns itens existem numa lista ou não usando as keywords in e not in ,
por exemplo.:

my_list = ["A", "B", 1, 2]

print("A" in my_list) # outputs: True


print("C" not in my_list) # outputs: True
print(2 not in my_list) # outputs: False

Exercício 1

Qual é o output do seguinte snippet?

list_1 = ["A", "B", "C"]


list_2 = list_1
list_3 = list_2

del list_1[0]
del list_2[0]

print(list_3)

Verifique

['C']

Exercício 2

Qual é o output do seguinte snippet?

list_1 = ["A", "B", "C"]


list_2 = list_1
list_3 = list_2

del list_1[0]
del list_2

print(list_3)

Verifique

['B', 'C']

Exercício 3

Qual é o output do seguinte snippet?

list_1 = ["A", "B", "C"]


list_2 = list_1
list_3 = list_2

del list_1[0]
del list_2[:]

print(list_3)

Verifique
[]

Exercício 4

Qual é o output do seguinte snippet?

list_1 = ["A", "B", "C"]


list_2 = list_1[:]
list_3 = list_2[:]

del list_1[0]
del list_2[0]

print(list_3)
Verifique

['A', 'B', 'C']

Exercício 5

Insira in ou not in em vez de ??? para que o código faça output do resultado esperado.

my_list = [1, 2, "in", True, "ABC"]

print(1 ??? my_list) # outputs True


print("A" ??? my_list) # outputs True
print(3 ??? my_list) # outputs True
print(False ??? my_list) # outputs False
Verifique

my_list = [1, 2, "in", True, "ABC"]

print(1 in my_list) # outputs True

print("A" not in my_list) # outputs True

print(3 not in my_list) # outputs True

print(False in my_list) # outputs False

Listas em listas
As listas podem consistir em escalares (nomeadamente números) e elementos de uma
estrutura muito mais complexa (já viu exemplos como strings, booleanos, ou mesmo
outras listas nas lições do Resumo da Secção anterior). Vamos analisar mais de perto o
caso em que os elementos de uma lista são apenas listas.

Encontramos frequentemente tais arrays (matrizes) nas nossas vidas. Provavelmente


o melhor exemplo disto é um tabuleiro de xadrez.

Um tabuleiro de xadrez é composto por linhas e colunas. Existem oito linhas (em
inglês, rows) e oito colunas. Cada coluna é marcada com as letras de A a H. Cada linha
é marcada com um número de um a oito.

A localização de cada campo é identificada por pares de letras-dígitos. Assim, sabemos


que o canto inferior esquerdo do tabuleiro (o que tem a torre branca) é A1, enquanto
que o canto oposto é H8.

Vamos assumir que somos capazes de utilizar os números selecionados para


representar qualquer peça de xadrez. Podemos também assumir que cada linha do
tabuleiro de xadrez é uma lista.

Veja o código abaixo:

row = []

for i in range(8):
row.append(WHITE_PAWN)

Constrói uma lista contendo oito elementos que representam a segunda linha do
tabuleiro de xadrez - a que está cheia de peões (suponha que WHITE_PAWN é um
símbolo pré-definido que representa um peão branco).

O mesmo efeito pode ser alcançado através de uma compreensão de lista, a sintaxe
especial utilizada por Python para preencher listas massivas.

Uma compreensão de lista é na realidade uma lista, mas criada durante a execução
do programa, e não é descrita estaticamente.

Veja o snippet:

row = [WHITE_PAWN for i in range(8)]


A parte do código colocada dentro dos parêntesis retos especifica:

• os dados a utilizar para preencher a lista ( WHITE_PAWN )


• a cláusula que especifica quantas vezes os dados ocorrem dentro da lista ( for
i in range(8) )

Deixe-nos mostrar-lhe alguns outros exemplos de compreensão de lista:

Exemplo #1:

squares = [x ** 2 for x in range(10)]

O snippet produz uma lista de dez elementos preenchida com quadrados de dez
números inteiros começando do zero (0, 1, 4, 9, 16, 25, 36, 49, 64, 81)

Exemplo #2:

twos = [2 ** i for i in range(8)]

O snippet cria um array de oito elementos contendo as primeiras oito potências de


dois (1, 2, 4, 8, 16, 32, 64, 128)

Exemplo #3:

odds = [x for x in squares if x % 2 != 0 ]

O snippet faz uma lista apenas com os elementos ímpares da lista squares .
Listas em listas: arrays bidimensionais
Vamos também assumir que um símbolo pré-definido chamado EMPTY designa um
campo vazio no tabuleiro de xadrez.

Assim, se quisermos criar uma lista de listas representando todo o tabuleiro de xadrez,
isso pode ser feito da seguinte forma:

board = []

for i in range(8):
row = [EMPTY for i in range(8)]
board.append(row)

Nota:

• a parte interior do loop cria uma linha composta por oito elementos (cada um
deles igual a EMPTY ) e anexa-o à lista board ;
• a parte externa repete-o oito vezes;
• no total, a lista board consiste em 64 elementos (todos iguais a EMPTY )

Este modelo imita perfeitamente o verdadeiro tabuleiro de xadrez, que é de facto uma
lista de oito elementos, sendo todos eles filas únicas. Vamos resumir as nossas
observações:

• os elementos das filas são campos, oito deles por fila;


• os elementos do tabuleiro de xadrez são linhas, oito delas por tabuleiro de
xadrez.

A variável board é agora um array bidimensional. Também é chamada, por analogia


aos termos algébricos, uma matriz.
Como as compreensões de lista podem ser nested, podemos encurtar a criação do
tabuleiro da seguinte forma:

board = [[EMPTY for i in range(8)] for j in range(8)]

A parte interior cria uma fila, e a parte exterior constrói uma lista de filas.

Listas em listas: arrays bidimensionais - continuação


O acesso ao campo selecionado do tabuleiro requer dois índices - o primeiro seleciona
a linha; o segundo - o número do campo dentro da linha, que é de facto um número
de coluna.

Dê uma vista de olhos no tabuleiro de xadrez. Cada campo contém um par de índices
que devem ser dados para aceder ao conteúdo do campo:
Olhando para a figura mostrada acima, vamos colocar algumas peças de xadrez no
tabuleiro. Primeiro, vamos adicionar todas as torres (em inglês, rooks):

board[0][0] = ROOK
board[0][7] = ROOK
board[7][0] = ROOK
board[7][7] = ROOK
Se quiser acrescentar um cavaleiro (knight) ao C4, faça-o da seguinte forma:

board[4][2] = KNIGHT

E agora um peão (pawn) para E5:

board[3][4] = PAWN

E agora - experimente o código no editor.

Natureza multidimensional das listas: aplicações


avançadas
Vamos aprofundar a natureza multidimensional das listas. Para encontrar qualquer elemento
de uma lista bidimensional, é preciso utilizar duas coordenadas:

• uma vertical (número da fila)


• e uma horizontal (número da coluna).

Imagine que desenvolve uma peça de software para uma estação meteorológica automática. O
dispositivo regista a temperatura do ar numa base horária e fá-lo ao longo de todo o mês. Isto
dá-lhe um total de 24 & vezes; 31 = 744 valores. Vamos tentar criar uma lista capaz de
armazenar todos estes resultados.

Primeiro, tem de decidir que tipo de dados serão adequados para esta aplicação. Neste caso,
um float seria melhor, uma vez que este termómetro é capaz de medir a temperatura com
uma precisão de 0,1 ℃.

De seguida, toma uma decisão arbitrária de que as filas registarão as leituras de hora em hora
(por isso a fila terá 24 elementos) e que cada uma das filas será atribuída a um dia do mês
(vamos supor que cada mês tem 31 dias, por isso precisa de 31 filas). Aqui está o par
apropriado de compreensões ( h é para hora, d para dia):

temps = [[0.0 for h in range(24)] for d in range(31)]

Toda a matriz está agora preenchida com zeros. Pode assumir que é atualizada
automaticamente utilizando agentes especiais de hardware. O que tem de fazer é esperar que a
matriz seja preenchida com medições.
Agora é altura de determinar a temperatura média mensal ao meio-dia. Some todas as 31
leituras registadas ao meio-dia e divida a soma por 31. Pode assumir que a temperatura à
meia-noite é armazenada em primeiro lugar. Aqui está o código relevante:

temps = [[0.0 for h in range(24)] for d in range(31)]


#
# The matrix is magically updated here.
#

total = 0.0

for day in temps:


total += day[11]

average = total / 31

print("Average temperature at noon:", average)

Nota: a variável day usada pelo loop for não é um escalar - cada passagem através da
matriz temps atribui-a com as linhas subsequentes da matriz; portanto, é uma lista. Tem que
ser indexado com 11 para aceder ao valor da temperatura medida ao meio-dia.

Agora encontre a temperatura mais alta durante todo o mês - veja o código:

temps = [[0.0 for h in range(24)] for d in range(31)]


#
# The matrix is magically updated here.
#

highest = -100.0

for day in temps:


for temp in day:
if temp > highest:
highest = temp

print("The highest temperature was:", highest)

Nota:

• a keyword day itera através de todas as linhas na matriz temps ;


• a variável temp itera através de todas as medições efetuadas num dia.
Agora conte os dias em que a temperatura ao meio-dia era de pelo menos 20 ℃:

temps = [[0.0 for h in range(24)] for d in range(31)]


#
# The matrix is magically updated here.
#

hot_days = 0

for day in temps:


if day[11] > 20.0:
hot_days += 1

print(hot_days, "days were hot.")

Arrays tridimensionais
O Python não limita a profundidade da inclusão list-in-list. Aqui pode ver um exemplo
de um array tridimensional:

Imagine um hotel. É um enorme hotel constituído por três edifícios, com 15 andares
cada um. Há 20 quartos em cada andar. Para tal, é necessário um array que possa
recolher e processar informações sobre os quartos ocupados/livres.

Primeiro passo - o tipo de elementos do array. Neste caso, um valor booleano


( True / False ) caberia.

Segundo passo - análise calma da situação. Resumir a informação disponível: três


edifícios, 15 andares, 20 quartos.

Agora pode criar o array:

rooms = [[[False for r in range(20)] for f in range(15)] for t in


range(3)]

O primeiro index ( 0 através 2 ) seleciona um dos edifícios; o segundo ( 0 através 14 )


seleciona o andar, o terceiro ( 0 através 19 ) seleciona o número do quarto. Todos os
quartos estão inicialmente livres.

Agora pode reservar um quarto para dois recém-casados: no segundo edifício, no


décimo andar, quarto 14:
rooms[1][9][13] = True

e libertar o segundo quarto no quinto andar, localizado no primeiro edifício:

rooms[0][4][1] = False

Verifique se há vagas no 15º andar do terceiro edifício:

vacancy = 0

for room_number in range(20):

if not rooms[2][14][room_number]:

vacancy += 1

A variável vacancy contém 0 se todos os quartos estiverem ocupados, ou o número


de quartos disponíveis, caso contrário.

Parabéns! Conseguiu chegar ao fim do módulo. Continue com o bom trabalho!

Key takeaways

1. A compreensão de lista permite-lhe criar novas listas a partir de listas existentes de uma
forma concisa e elegante. A sintaxe de uma compreensão de lista é a seguinte:

[expression for element in list if conditional]


que é na verdade um equivalente ao seguinte código:

for element in list:


if conditional:
expression

Eis um exemplo de compreensão de uma lista - o código cria uma lista de cinco elementos
preenchida com os primeiros cinco números naturais elevados à potência de 3:

cubed = [num ** 3 for num in range(5)]


print(cubed) # outputs: [0, 1, 8, 27, 64]

2. Pode usar listas nested em Python para criar matrizes (ou seja, listas bidimensionais). Por
exemplo:

# A four-column/four-row table - a two dimensional array (4x4)

table = [[":(", ":)", ":(", ":)"],


[":)", ":(", ":)", ":)"],
[":(", ":)", ":)", ":("],
[":)", ":)", ":)", ":("]]

print(table)
print(table[0][0]) # outputs: ':('
print(table[0][3]) # outputs: ':)'
3. Pode fazer nest de quantas lists-in-lists quiser, e portanto criar listas n-dimensionais, por
exemplo, três, quatro ou mesmo sessenta e quatro arrays dimensionais. Por exemplo:

# Cube - a three-dimensional array (3x3x3)

cube = [[[':(', 'x', 'x'],


[':)', 'x', 'x'],
[':(', 'x', 'x']],

[[':)', 'x', 'x'],


[':(', 'x', 'x'],
[':)', 'x', 'x']],

[[':(', 'x', 'x'],


[':)', 'x', 'x'],
[':)', 'x', 'x']]]

print(cube)
print(cube[0][0][0]) # outputs: ':('
print(cube[2][2][0]) # outputs: ':)'

Você também pode gostar