Escolar Documentos
Profissional Documentos
Cultura Documentos
LAB Python MODULO III
LAB Python MODULO III
Módulo 3
Valores Booleanos, Execução Condicional, Loops, Listas e Processamento de Lista,
Operações Lógicas e Bitwise
Perguntas e respostas
Um programador escreve um programa e o programa faz perguntas.
Nunca obterá uma resposta como Deixe-me pensar...., Não sei, ou Provavelmente sim, mas não
tenho a certeza.
Exercícios
Agora vamos fazer algumas perguntas. Tente adivinhar as respostas.
2 == 2 Verifique
2 == 2. Verifique
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.
black_sheep == 2 * white_sheep
black_sheep == (2 * white_sheep)
Se quiser saber se há mais ovelhas pretas do que brancas, pode escrevê-lo da seguinte forma:
Vamos verificar se existe o risco de ser multado pela polícia rodoviária (a primeira pergunta é
rigorosa, a segunda não).
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.
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
Input de amostra: -5
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
• 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.
• 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.
Como se pode ver, almoçar não é uma atividade condicional e não depende do tempo.
if the_weather_is_good:
go_for_a_walk()
have_lunch()
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 .)
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.
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
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).
• 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.
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()
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.
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:
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.
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()
Isto pode parecer um pouco confuso, mas esperemos que alguns exemplos simples ajudem a
lançar mais luz.
Exemplo 1:
Vamos começar com o caso mais simples - como identificar o maior de dois
números:
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:
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.
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.
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.
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.
largest_number = -999999999
number = int(input())
if number == -1:
print(largest_number)
exit()
if number > largest_number:
largest_number = number
# Go to line 02
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:
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:
Teste o seu código utilizando os dados que lhe fornecemos. E arranje também um
Spathiphyllum!
Dados de Teste
Input de amostra: spathiphyllum
LAB
Tempo estimado
10-20 minutos
Nível de dificuldade
Fácil/Médio
Objetivos
Familiarizar o aluno a:
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:
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.
Dados de teste
Input de amostra: 10000
LAB
Tempo estimado
10-25 minutos
Nível de dificuldade
Fácil/Médio
Objetivos
Familiarizar o aluno a:
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.
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 % .
Dados de teste
Input de amostra: 2000
Key takeaways
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:
x = 10
if x == 10: # condition
print("x is equal to 10") # Executed if the condition is
True.
x = 10
x = 10
else:
print("x is greater than or equal to 10") # Executed if
the condition is False.
x = 10
if x > 5: # True
print("x > 5")
if x > 8: # True
print("x > 8")
else:
print("else will be executed")
x = 10
if x == 10: # True
print("x == 10")
else:
print("else will not be executed")
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")
Exercício 1
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
x, y, z = 5, 10, 8
x, y, z = z, y, x
print(x > z)
print((y - 5) == x)
Verifique
Exercício 4
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
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
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
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 .
Nota: todas as regras relativas à indentação são aplicáveis também aqui. Vamos mostrar-lhe
isso em breve.
while conditional_expression:
instruction_one
instruction_two
instruction_three
:
:
instruction_n
• 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
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:
Verifique como este código implementa o algoritmo que lhe mostrámos anteriormente.
Os loops loop while : mais exemplos
odd_numbers = 0
even_numbers = 0
# 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)
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 .
counter = 5
while counter:
print("Inside the loop.", counter)
counter -= 1
print("Outside the loop.", counter)
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:
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.
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.
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
• 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)
for i in range(10):
print("The value of i is currently", i)
Nota:
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.
Consegue dizer-nos quantas linhas irão aparecer na consola, e que valores irão
conter?
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.
Nota: se o conjunto gerado pela função range() está vazio, o loop não irá executar de todo o
seu corpo.
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.
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?
LAB
Tempo estimado
5-15 minutos
Nível de dificuldade
Muito fácil
Objetivos
Familiarizar o aluno a:
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!
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!"
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
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.
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.")
largest_number = -99999999
counter = 0
if counter:
print("The largest number is", largest_number)
else:
print("You haven't entered any number.")
LAB
Tempo estimado
10-20 minutos
Nível de dificuldade
Fácil
Objetivos
Familiarizar o aluno a:
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:
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.
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 .
Dados de teste
Input de amostra: Gregory
Output esperado:
G
R
G
R
Y
Output esperado:
B
S
T
M
S
LAB
Tempo estimado
5-15 minutos
Nível de dificuldade
Fácil
Objetivos
Familiarizar o aluno a:
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 .
Dados de teste
Input de amostra: Gregory
Output esperado:
GRGRY
Input de amostra: abstemious
Output esperado:
BSTMS
Vamos mostrar-lhe como funciona - tente julgar por si próprio se é utilizável e se pode
viver sem ela ou não.
Como pode ter suspeitado, os loops podem ter o ramo else também, como if .
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?
i = 111
for i in range(2, 1):
print(i)
else:
print("else:", i)
O corpo do loop não será executado aqui. Nota: atribuímos a variável i antes do loop.
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 .
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:
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 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.
Dados de teste
Input de amostra: 6
Input de amostra: 20
Input de amostra: 2
Tempo estimado
20 minutos
Nível de dificuldade
Médio
Objetivos
Familiarizar o aluno a:
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:
É 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.
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
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
• 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)
• 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()
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:
Código de exemplo:
for i in range(3):
print(i, end=" ") # Outputs: 0 1 2
Crie um loop for que conta de 0 a 10, e imprime os números ímpares no ecrã. Use o esqueleto
abaixo:
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:
Verifique
Exercício 5
n = 3
while n > 0:
print(n + 1)
n -= 1
else:
print(n)
Verifique
Exercício 6
n = range(4)
for num in n:
print(num - 1)
else:
print(num)
Verifique
Exercício 7
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:
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:
O resultado fornecido pelo operador and pode ser determinado com base na tabela da
verdade.
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:
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))
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.
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.
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).
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
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
logneg = not i
A variável logneg será definida como False - nada mais precisa de ser feito.
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
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
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:
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á:
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):
x | 1 = 1
x | 0 = x
Agora está pronto para definir o seu bit com uma das seguintes instruções:
x ^ 1 = ~x
x ^ 0 = x
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.
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.
O argumento à esquerda destes operadores é um valor inteiro cujos bits são deslocados.
O argumento à direita determina o tamanho do shifting.
A prioridade destes operadores é muito alta. Vê-los-á na tabela de prioridades atualizada, que
lhe mostraremos no final desta secção.
17 68 8
output
Nota:
Key takeaways
2. Pode utilizar operadores bitwise para manipular bits únicos de dados. Os seguintes dados de
amostra:
• & 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,
Exercício 1
x = 1
y = 0
Verifique
Exercício 2
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
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:
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.
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?
numbers = [10, 5, 7, 2, 1]
numbers[0] = 111
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]
numbers[0] = 111
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.
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:
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.
Veja a última linha de código no editor, execute o programa e verifique que valor irá
imprimir para a consola. Consegue adivinhar?
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.
print(numbers[-1])
print(numbers[-2])
LAB
Tempo estimado
5 minutos
Nível de dificuldade
Muito fácil
Objetivos
Familiarizar o aluno a:
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).
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.
result = function(arg)
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.
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.
list.insert(location, value)
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.
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.
É 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.
my_list = [10, 1, 8, 3, 5]
total = 0
for i in my_list:
total += i
print(total)
Veja o snippet:
variable_1 = 1
variable_2 = 2
variable_2 = variable_1
variable_1 = variable_2
variable_1 = 1
variable_2 = 2
auxiliary = variable_1
variable_1 = variable_2
variable_2 = auxiliary
variable_1 = 1
variable_2 = 2
Listas em ação
Agora pode facilmente trocar os elementos da lista para inverter a sua ordem:
my_list = [10, 1, 8, 3, 5]
print(my_list)
[5, 3, 8, 1, 10]
output
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.
my_list = [10, 1, 8, 3, 5]
length = len(my_list)
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.
LAB
Tempo estimado
10-15 minutos
Nível de dificuldade
Fácil
Objetivos
Familiarizar o aluno a:
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 é:
A propósito, é fã dos Beatles? (Os Beatles são uma das bandas favoritas de Greg. Mas
calma...quem é o Greg....?)
Key takeaways
print(my_list[-1]) # outputs: 0
my_list[1] = '?'
my_list.insert(0, "first")
my_list.append("last")
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.
my_list = [1, 2, 3, 4]
del my_list[2]
5. As listas podem ser iteradas através da utilização do loop for , por exemplo:
print(color)
6. A função len() pode ser usada para verificar o comprimento da lista, por exemplo:
print(len(my_list)) # outputs 5
del my_list[2]
print(len(my_list)) # outputs 4
Exercício 1
lst = [1, 2, 3, 4, 5]
lst.insert(1, 6)
del lst[0]
lst.append(1)
print(lst)
Verifique
Exercício 2
lst = [1, 2, 3, 4, 5]
lst_2 = []
add = 0
add += number
lst_2.append(add)
print(lst_2)
Verifique
Exercício 3
lst = []
del lst
print(lst)
Verifique
Exercício 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.
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.
8 10 6 2 4
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
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
2 6 4 8 10
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.
Deverá ser capaz de ler e compreender este programa sem quaisquer problemas:
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)
Se quiser que o Python ordene a sua lista, pode fazê-lo desta forma:
[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()
lst = [5, 3, 1, 2, 4]
print(lst)
lst.reverse()
Exercício 1
lst.sort()
print(lst)
Verifique
Exercício 2
a = 3
b = 1
c = 2
lst = [a, c, b]
lst.sort()
print(lst)
Verifique
[1, 2, 3]
Exercício 3
a = "A"
b = "B"
c = "C"
d = " "
lst = [a, b, c, d]
lst.reverse()
print(lst)
Verifique
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:
A parte surpreendente é o facto de que o programa fará o output: [2] , não [1] , que
parece ser a solução óbvia.
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.
Uma slice é um elemento da sintaxe Python que lhe permite fazer uma cópia
completamente nova de uma lista ou partes de uma lista.
list_1 = [1]
list_2 = list_1[:]
list_1[0] = 2
print(list_2)
Esta parte inconspícua do código descrito como [:] é capaz de produzir uma lista
completamente nova.
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 ).
my_list[start:end]
Para repetir:
my_list = [10, 8, 6, 4, 2]
new_list = my_list[1:-1]
print(new_list)
O output do snippet é:
[8, 6, 4]
output
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 .
my_list[:end]
my_list[0:end]
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) .
my_list[start:]
my_list[start:len(my_list)]
my_list = [10, 8, 6, 4, 2]
new_list = my_list[3:]
print(new_list)
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)
my_list = [10, 8, 6, 4, 2]
del my_list[:]
print(my_list)
Veja:
my_list = [10, 8, 6, 4, 2]
del my_list
print(my_list)
elem in my_list
elem not in my_list
O primeiro deles tenta encontrar o maior valor na lista. Veja o código no editor.
for i in my_list:
if i > largest:
largest = i
print(largest)
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?
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:
print(hits)
Nota:
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.
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_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:
3. Também se podem utilizar índices negativos para executar slices. Por exemplo:
my_list = [1, 2, 3, 4, 5]
slice_one = my_list[2: ]
slice_two = my_list[ :2]
slice_three = my_list[-2: ]
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.:
Exercício 1
del list_1[0]
del list_2[0]
print(list_3)
Verifique
['C']
Exercício 2
del list_1[0]
del list_2
print(list_3)
Verifique
['B', 'C']
Exercício 3
del list_1[0]
del list_2[:]
print(list_3)
Verifique
[]
Exercício 4
del list_1[0]
del list_2[0]
print(list_3)
Verifique
Exercício 5
Insira in ou not in em vez de ??? para que o código faça output do resultado esperado.
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.
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.
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:
Exemplo #1:
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:
Exemplo #3:
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:
A parte interior cria uma fila, e a parte exterior constrói uma lista de filas.
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
board[3][4] = PAWN
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):
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:
total = 0.0
average = total / 31
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:
highest = -100.0
Nota:
hot_days = 0
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.
rooms[0][4][1] = False
vacancy = 0
if not rooms[2][14][room_number]:
vacancy += 1
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:
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:
2. Pode usar listas nested em Python para criar matrizes (ou seja, listas bidimensionais). Por
exemplo:
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:
print(cube)
print(cube[0][0][0]) # outputs: ':('
print(cube[2][2][0]) # outputs: ':)'