Mostrar mensagens com a etiqueta sorted(). Mostrar todas as mensagens
Mostrar mensagens com a etiqueta sorted(). Mostrar todas as mensagens

segunda-feira, 17 de outubro de 2016

E finalmente os dicionários

Vamos então falar finalmente sobre dicionários. Estas estruturas são também parecidas com as listas, mas têm a particularidade de serem construídas por pares de chave:valor. A ideia é termos uma correspondência direta entre valores. Nada como um exemplo para ilustrar:
>>> dicio = {0:'zero', 1:'um', 'UM':1, 'ZERO':0}
>>> dicio[0]
'zero'
>>> dicio['UM']
1
Comentários: o dicionário cria-se com chavetas {}, e cada par chave:valor é separado por dois pontos :, enquanto os pares são separados por vírgula. Podemos então aceder ao valor correspondente a cada chave usando a notação dicionário[chave]. As chaves e os valores podem assumir o tipo que quisermos, seja um número inteiro ou com vírgula, uma cadeia de caracteres ou mesmo um tuplo. Mas enquanto as chaves têm que ser imutáveis, não podendo aceitar listas como tipo, os valores podem aceitar listas. Além disso, não podem existir duas chaves iguais, e se ocorrer, a chave que permanece válida é a última a ser inserida. Um exemplo funciona melhor:
>>> dicio = {0:'zero', 1:'um', 0:'ZERO'} # reparar nos dois 0!!
>>> dicio[0]
'ZERO'
Eu estou sempre a apresentar outras coisas: para fazermos um comentário em Python, basta escrever o símbolo de cardinal # e daí para a frente é tudo ignorado nessa linha. Isto também se aplica a programas em Python. E acho que o exemplo acima explica-se a si mesmo.
Também podemos alterar, adicionar e eliminar elementos num dicionário:
>>> dicio2 = {'Nome':'Chico', 'Idade':25}
>>> dicio2['Nome']
'Chico'
>>> dicio2['Nome'] = 'Francisco' # alterar o valor da chave 'Nome'
>>> dicio2['Nome']
>>> dicio2['Apelido'] = 'Santos' # adicionar uma nova chave
>>> dicio2   # ver o conteúdo do dicionário
{'Idade': 25, 'Nome': 'Francisco', 'Apelido': 'Santos'}
>>> del dicio2['Idade'] # apagar o par de chave 'Idade'
>>> dicio2
{'Nome': 'Francisco', 'Apelido': 'Santos'}
>>> del dicio2 # apagar o dicionário todo
Assim já ficamos com uma boa ideia do que se pode fazer com dicionários! De notar que não se pode fazer slicing com dicionários. Mas podemos iterá-los com um ciclo for:
dicio = {'Idade': 25, 'Nome': 'Francisco', 'Apelido': 'Santos'}
for i in dicio:
    print(i, dicio[i])
Isto vai dar:
Idade 25
Nome Francisco
Apelido Santos
Também podemos usar as funções min(), max(), len() e sorted(), e também o operador in. Vejamos como funcionam:
>>> dicio = {'Idade': 25, 'Nome': 'Francisco', 'Apelido': 'Santos'}
>>> min(dicio) # resulta na primeira chave, em ordem alfabética
'Apelido'
>>> max(dicio) # resulta na última chave, em ordem alfabética
'Nome'
>>> len(dicio)
3
>>> sorted(dicio) # ordenar as chaves alfabeticamente
['Apelido', 'Idade', 'Nome']
>>> 'Nome' in dicio # ver se 'Nome' é uma chave
True
>>> 'Santos' in dicio # ver se 'Santos' é uma chave
False
Como deve ter notado, todas estas funções se aplicam às chaves. Para aceder diretamente a valores, teremos de voltar a este tema mais tarde, depois de falarmos de programação por objetos.
Finalmente, vamos falar na função geradora de um dicionário, dict():
>>> dicio = dict(Idade=25, Nome='Francisco', Apelido='Santos')
>>> dicio
{'Apelido': 'Santos', 'Idade': 25, 'Nome': 'Francisco'}
Como se percebe, usa-se como argumento pares chave=valor separados por vírgulas, com a nota de que aqui a chave tem que ser uma cadeia de caracteres.
E pronto, para a semana há mais!

segunda-feira, 10 de outubro de 2016

Mais estruturas de dados: os tuplos

Realmente, já vamos para a 13ª contribuição para este blogue e ainda não falámos em duas estruturas de dados muito importantes em Python: os tuplos e os dicionários. Estas estruturas fazem lembrar as listas, mas têm características próprias. Vamos começar pelos tuplos. Um tuplo é como uma lista, mas os seus elementos são imutáveis. Cria-se como se cria uma lista, só que em vez de parêntesis retos [], usam-se parêntesis curvos (), embora estes sejam opcionais na sua criação:
>>> (1,2,3)
(1, 2, 3)
>>> 1,2,3
(1, 2, 3)
Tal como numa lista, podemos usar slicing para aceder a vários elementos:
>>> a=(1,2,3,4,5,6)
>>> a[1]
2
>>> a[2:4]
(3, 4)
>>> a[::2]
(1, 3, 5)
>>> a[1::2]
(2, 4, 6)
Tal como com as listas, nos tuplos podemos obter o elemento 1 (a contar a partir do elemento 0) e os elementos 2 a 4, excluindo o 4. Aqui aproveito e mostro outra maneira de fazer o slicing: com três parâmetros. Os dois primeiros continuam a ser o primeiro e o último, excluindo o último. Se não indicarmos nenhum, cobre todos os elementos, mas o terceiro parâmetro indica qual o salto entre elementos. Nos exemplos acima, salta de 2 em 2 elementos. Giro, não é? Isto também funciona com cadeias de caracteres:
>>> 'Teste de saltarelos'[::2]
'Tsed atrls'
>>> 'Teste de saltarelos'[::-1]
'soleratlas ed etseT'
>>> 'Teste de saltarelos'[::-3]
'setsdtT'
Bem, mas voltemos aos tuplos. Como já mencionei, ao contrário das listas, os tuplos são imutáveis. Assim, não podemos alterar um elemento de um tuplo, nem apagar um elemento. Só podemos adicionar elementos (que corresponde a criar um tuplo novo):
>>> a = (1,)
>>> a = a + (2,3)
>>> a
(1, 2, 3)
Algumas notas: sim, quando fazemos o tuplo de um só elemento (1,), tem de ter uma vírgula, para não se confundir com um cálculo com parêntesis. Podemos mesmo retirar os parêntesis, mas a vírgula tem de ficar.
E tal como com as listas, também podemos iterar os tuplos:
nums = (1, 4, 5, 6, 3)
for i in nums:
    print(i)
Vai resultar em:
1
4
5
6
3
Em comum com as listas, os tuplos também aceitam as funções max(), min(), sum(), len(), reversed() e o operador in, que funcionam exatamente da mesma maneira. Também podemos aplicar a função sorted() num tuplo, mas o resultado é uma lista. E também temos uma função que cria tuplos, que incrivelmente se chama tuple():
>>> tuple(reversed([6,4,2,7,9]))
(9, 7, 2, 4, 6)
Esta função, tal como a sua análoga list(), também tem outras aplicações, ilustradas a seguir:
>>> tuple('Python')
('P', 'y', 't', 'h', 'o', 'n')
>>> tuple(range(6))
(0, 1, 2, 3, 4, 5)
Voltando atrás à atribuição de variáveis, vemos agora que a atribuição de várias variáveis separadas por vírgulas (um,dois,tres = 1,2,3) não é mais do que usar um tuplo para este fim...
Finalmente, porquê este nome de 'tuplo'? Bem, se pensarmos nos nomes 'duplo', 'triplo', 'quádruplo'... 'múltiplo', vemos que foi daí que veio. As coisas que vamos aprendendo...

segunda-feira, 26 de setembro de 2016

Funções e listas

Já andámos a ver várias funções, de conversão ou matemáticas. Mas agora vamos abordar algumas funções que afetam listas. Comecemos por algumas bastante simples e diretas:
>>> max([1,5,3,7,8,2])
8
>>> min([1,5,3,7,8,2])
1
>>> sum([1,5,3,7,8,2])
26
Claro que estas funções apenas resultam se as listas contiverem apenas números. Como seria de esperar, a função max() apresenta o maior número na lista, a função min() apresenta o menor, e a função sum() apresenta a soma de todos os números na lista. As funções max() e min() também podem usar como argumento números ou variáveis separados por vírgulas:
>>> max(1,5,3,7,8,2)
8
>>> min(1,5,3,7,8,2)
1
Também temos um outro operador que funciona tanto em listas como em cadeias de caracteres, o operador in, que testa se algo se encontra numa lista (ou numa cadeia de caracteres) e responde com um booleano:
>>> 4 in [1,2,3,4]
True
>>> 0 in [4,8,7,4,9]
False
>>> 'a' in 'antonio'
True
>>> 'b' in 'antonio'
False
De notar que é a segunda vez que aparece o operador in, pois também é usado de modo diferente nos ciclos for.
E agora vamos ver outra função que é muito comum em várias linguagens: len(). Sendo a abreviatura de length (comprimento), resulta no comprimento de várias estruturas:
>>> len('batata')
6
>>> len([4,8,7,4,9])
5
Aplicado a cadeias de caracteres, diz-nos quantos tem, e em listas, indica o número de elementos da lista mais externa (sim, as listas podem ter listas como elementos).
Ora então chegamos finalmente a range(). No Python 2.x, era uma função que produzia uma lista, mas na versão 3.x produz uma sequência imutável. Antes de mais, o que faz isto? Em Python 2.x, fazia:
>>> range(3)
[0, 1, 2]
>>> range(3,6)
[3, 4, 5]
>>> range(1,11,2)
[1, 3, 5, 7, 9]
Em suma, quando só tem um argumento, range produzia uma lista de zero até esse argumento excluindo-o. Com dois argumentos, indica qual o número de onde começa e até onde vai, excluindo o final. Com 3 argumentos, é como com 2 mas o último argumento indica quanto se soma em cada iteração. Em Python 3.x, é quase a mesma coisa, mas se em 2.x se produzia uma lista que se podia depois modificar, em 3.x produz-se uma "lista-usa-e-deita-fora". Os exemplos acima em Python 3.x vão dar:
>>> range(3)
range(0, 3)
>>> range(3,6)
range(3, 6)
>>> range(1,11,2)
range(1, 11, 2)
Parece confuso, mas na realidade a diferença é subtil. range() é muito usado em conjunto com o comando for, como no programa abaixo:
for i in range(0,15,3):
    print(i)
que vai resultar em:
0
3
6
9
12
Este resultado seria o mesmo em Python 2.x. Mais tarde voltaremos a estas sequências imutáveis...
Falando ainda destas sequências, temos mais uma função que resulta numa destas, a função reversed(). Como o próprio nome indica, esta função inverte a sequência de uma lista que lhe seja fornecida como argumento, e resulta num iterável que corresponde à sequência invertida. Aqui já não há diferença de versões. Para aceder ao resultado, temos de iterar cada um dos elementos, como por exemplo:
for i in reversed([6,4,2,7,9]):
    print(i)
dá o seguinte:
9
7
2
4
6
Se experimentar:
>>> reversed([6,4,2,7,9])
<list_reverseiterator object at 0x02AEFA30>
O que não dá muito jeito... Mas felizmente, temos outra função que trata disto: list(). Esta converte o seu argumento numa lista, o que já dá muito jeito!
>>> list(reversed([6,4,2,7,9]))
[9, 7, 2, 4, 6]
Já agora, a função list() tem outras aplicações, ilustradas a seguir:
>>> list('Python')
['P', 'y', 't', 'h', 'o', 'n']
>>> list(range(6))
[0, 1, 2, 3, 4, 5]
Isto já permite umas coisas engraçadas, se puxar pela imaginação...
E vamos terminar com uma última função, sorted(), que serve para ordenar uma lista. Os exemplos são bastante elucidativos:
>>> sorted([6,4,2,7,9])
[2, 4, 6, 7, 9]
>>> sorted([6,4,2,7,9], reverse=True)
[9, 7, 6, 4, 2]
Como dá para perceber, podemos escolher a ordem, ascendente ou descendente, dependendo do valor que atribuímos ao argumento opcional reverse. E por hoje é tudo!