Ciclos contados
Até agora quando utilizamos ciclos , e em particular para percorrer tuplos, temos inicializado um contador e, no corpo do ciclo, fazemos avançar o contador. No caso dos tuplos, inicializamos um contador i=0
e avançamos o mesmo com i=i+1
. Vamos agora ver como podemos utilizar ciclos contados para tingir o mesmo fim.
Num ciclo contado a execução é controlada por uma variável de controlo. Em geral, num ciclo contado especificamos o valor inicial da variável de controlo, a forma de actualizar a mesma, e a condição de paragem. Logo, um ciclo contado permite iterar sobre uma sequência de valores.
Em Python utilizamos a instrução for
para definir ciclos contados e temos a seguinte sintaxe (em BNF):
<instrução for> ::= for <nome simples> in <expressão>: NEWLINE <bloco de instruções>
Neste caso o <nome simples>
corresponde à variável de controlo e o valor <expressão>
tem de ser uma sequência, e.g., um tuplo. Veremos adiante que existem várias entidades em Python que podem ser vistas como sequências, também designadas de iteráveis. O comportamento da instrução for
consiste em executar o corpo do ciclo para cada elemento na sequência resultante de avaliar a <expressão>
. Tal como na instrução while
, na instrução for
podemos utilizar a instrução break
no corpo do ciclo (ou bloco de instruções) para interromper o mesmo independentemente do valor da variável de controlo.
Vejamos alguns exemplos.
def soma(t): resultado = 0 for x in t: resultado = resultado + x return resultado soma((1,2,3,4,5))
Para gerar sequências em Python podemos utilizar a função pré-definida range
. Em BNF,
range(<argumentos>) <argumentos> ::= <expressão> | <expressão>, <expressão> | <expressão, <expressão>, <expressão>
Em que os valores de cada <expressão> são do tipo inteiro e o resultado é uma sequência. O primeiro argumento define o início da sequência (inclusive), o segundo argumento define o fim da sequência (exclusive), e terceiro argumento define o passo ou incremento.
Exemplos:
>>> tuple(range(10)) (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) >>> tuple(range(5,10)) (5, 6, 7, 8, 9) >>> tuple(range(-5,10)) (-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9) >>> tuple(range(-5,10,2)) (-5, -3, -1, 1, 3, 5, 7, 9) >>> tuple(range(-5,10,-2)) () >>> tuple(range(10,-5,-2)) (10, 8, 6, 4, 2, 0, -2, -4) >>> tuple(range(10,-5,-1)) (10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, -1, -2, -3, -4) >>>
Exercício 1: Defina uma função que calcula a soma dos primeiros $n$ números naturais.
Exercício 2: Defina uma função que permite verificar se um tuplo com valores numéricos está ordenado. Nota: Será que podemos iterar simplesmente sobre os elementos do tuplo? Justifique.
Nota-se que a instrução while
permite fazer tudo o que a instrução for
pode fazer. Por outro lado existem casos em que não podemos utilizar a instrução for
, com no caso da função alisa
vista na última aula. Em geral o uso da instrução for
é mais eficiente que a instrução while
, nomeadamente quando utilizamos a função range
, dado que o interpretador de Python tem um maior sucesso a optimizar esses casos. Portanto, a instrução for
deverá ser sempre preferida em detrimento da instrução while
quando possível.
Cadeias de caracteres
Anteriormente considerámos cadeias caracteres como constantes e vimos que são do tipo str
em Python. Em geral uma cadeia de caracteres pode conter 0 ou mais caracteres. As cadeias de caracteres em Python são delimitadas por '
s ou "
s. A sequência de caracteres com 0 caracteres, ou vazia, é representada por ''
ou ""
.
Nota-se que as "
s em Python são também utilizadas para documentação, uma utilização completamente distinta da que acabámos de ver:
def soma(t): """ Recebe um tuplo de retorna a soma dos seus elementos. """ resultado = 0 for x in t: resultado = resultado + x return resultado
Se esta definição estiver carregada, podemos obter a seguinte interacção:
>>> help(soma) Help on function soma in module __main__: soma(t) Recebe um tuplo de retorna a soma dos seus elementos. >>>
Tal como os tuplos, as cadeias de caracteres são imutáveis e podemos aceder aos caracteres por meio de índices. Exemplo:
>>> fp='Fundamentos da Programacao' >>> len(fp) 26 >>> fp[0] 'F' >>> fp[15:] 'Programacao' >>> fp[:11] 'Fundamentos' >>> fp[-3:] 'cao' >>>
Existem várias operações pré-definidas que podemos aplicar sobre cadeias de caracteres,
>>> fp1 = 'Fundamentos' >>> f = 'Fundamentos' >>> p = 'Programacao' >>> f + ' de ' + p 'Fundamentos de Programacao' >>> f*3 'FundamentosFundamentosFundamentos' >>> 'c' in p True >>> 'c' in f False >>> len(p) 11 >>> str(9+8) '17' >>> str((9,8,20)) '(9, 8, 20)' >>> eval('f + p') 'FundamentosProgramacao' >>>
Podemos também iterar sobre os caracteres. Vejamos o seguinte exemplo em que transformamos minúsculas em maiúsculas:
def toupper(s): for i in range(len(s)): if ord('a') <= ord(s[i]) <= ord('z'): s = s[:i] + chr(ord(s[i]) - ord('a') + ord('A')) + s[i+1:] return s
No exemplo anterior utilizámos também as funções pré-definidas char e ord que permitem obter o código de um caractere e obter um caractere para um dado código, respectivamente. Nota-se que os caracteres são representados por um código numérico, em que o código ASCII será o mais conhecido. O Python utiliza Unicode, que inclui o código ASCII.
Tendo por base esta representação numérica, podemos efetuar comparações entre caracteres e cadeias de caracteres:
>>> 'a' < 'z' True >>> 'a' < 'Z' False >>> 'a' > 'Z' True >>> 'Fundamentos' > 'Programacao' False >>> 'fundamentos' > 'Programacao' True >>> 'fundamentos' > 'fundao' False >>> 'fundamentos' < 'fundao' True >>>