Listas

Introdução

Uma lista é um recurso extremamente poderoso para trabalharmos com coleções de dados em uma linguagem de programação. Este é um recurso que esta presente em praticamente qualquer linguagem de progração existente, embora em algumas linguagens, usualmente a lista terá tamanho fixo e só poderá armazenar um único tipo de dado para todos os valores da mesma.

Podemos pensar em uma lista como uma variável que, em vez de armazernar um único valor, pode armazenar inúmeros valores dentro dela. Cada um destes valores vai receber um endereço, iremos chamar este enderenço de índice. Portanto se tivermos uma lista com 10 valores, teremos 10 indices diferentes para acessarmos cada um destes valores individualmente. É importante ressaltar que os índices da lista servirão para acessarmos e modificarmos cada um dos valores armazenados dentra lista. Os índices de uma lista são sempre números inteiros e começam em 0 (zero) e vão até N-1, onde N é a quantidade de emelemtnso da lista ou seu tamanho.

Uma forma interessante de visualizarmos uma lista é uma sequencia de caixinhas na horizontal, assim como uma caixa de correio de um condômínio, embora todas estas caixinhas estejam no mesmo local, cada uma delas vai possuir um número diferente, neste caso chamaremos este número sempre de índice. A a seguir tem uma representação gráfica de uma lista:

0 1 2 3 4
-404 565 -66 7734 54

Esta lista mostrada tem 5 valores armazenados dentro dela [-404, 565, -66, 7734, 54], observe que estes valores estão representados na segunda linha da figura de cima. Para cada um dos valores armazenados existe um índice, estes valores estão representados na primeira linha. Portanto o valor 565 tem índice 1, mesmo ele sendo o segundo elemento pois a contagem começa em 0. Note que o ultimo elemento sempre vai ter índice igual a N-1.

Agora você deve estar se perguntando para que vais usar uma lista, bom listas tem ínumeras utilidades justamente por poderem armazenar ínumeros valores em uma única variável. Imagine que você tem que escrever um pograma que leia 100 números e depois da leitura mostre estes números ordenados de forma crescente. Sem o uso de listas fica praticamente impossível de se escrever um porgrama deste tipo.

Criando uma lista em python.

Em python sempre vamos utilizar os colchetes, estes caracteres aqui -> "[" "]", para trabalharmos com listas. O próprio python imprime as listas utilizando os colchetes. O cochete de abertura [ indica que ali começa a lista e o de fechamento ] que ali termina a mesma.

Para criarmos uma lista vazia é muito simples, damos um nome de variável e dizemos que a lista abriu e fechou com os colchetes [].

Exemplo:

In [1]:
minhaLista = []
print minhaLista
[]

Acabamos de criar e de imprimir uma lista vazia, voce notou que o python imprimiu os dois colchetes? isso indica uma lista vazia.

Para criarmos uma lista já com alguns valores utilizamos praticamente a mesma sintaxe, entretanto, passamos os valores em ordem que vão estar dentro da lista separados por , (virgula).

Exemplo:

In [2]:
minhaLista = [-404, 565, -66, 7734, 54]
print minhaLista
[-404, 565, -66, 7734, 54]

Observe que agora, ao imprimir a lista o python mostra os cochetes (onde começa e onde termina a lista) e os valores que colocamos dentro da lista ao cria-la.

Uma coisa interessante do python é que ele permite que coloquemos vários valores de vários tipos dentro de uma lista.

Exemplo

In [3]:
minhaLista = [-404, "Cachorro Quente", False, 77.0]
print minhaLista
[-404, 'Cachorro Quente', False, 77.0]

Mas e esse tal de índice? Porque ele não aparece ali na impressão do python?

O índice não é impresso pois nós o utilizamos para acessar/modificar cada um dos valroes da lista individualmente.

Acesso a um valor individual em lista em python.

Muitas vezes vamos precisar acessar um valor especifico da lista ou para pegar o valor que está lá ou para modificar. Para isto, novamente utilizaremos os colchetes. A sintaxe é muito simples nome_da_lista[indice] podemos usar essa sintaxe tanto para acessar um valor quanto para modificar um valor da lista.

Exemplo:

In [4]:
lista = ['Listas','nao sao', 'legais']
print lista   #observe que este print vai imprimir a lista acima que tem 3 textos dentro dela.

#se quisermos pegar só um valor (posição) da lista podemos usar o índice
print lista[1] #observe que este print vai imprimir apenas a string q esta na posição de índice 1 da lista

#podemos usar a mesma ideia para mudar o que está na lista.
lista[1] =  'sao muito'

#imprimimos agora a posição modificada sozinha e posteriormente toda a lista
print lista[1] 
print lista
['Listas', 'nao sao', 'legais']
nao sao
sao muito
['Listas', 'sao muito', 'legais']

Viu que bacana. Então apenas com um nome de variavel conseguimos armazenar ínumeros valores dentro desta lista e com o índice acessar cada un detes valores.

A lista criada anteriormente tem tamanho 3 e possui os índices 0,1 e 2. O que será que acontece se tentarmos acessar o índice 3?

Exemplo:

In [5]:
lista = ['Listas','nao sao', 'legais']
print lista[3]
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-5-2ec37bc6fee9> in <module>()
      1 lista = ['Listas','nao sao', 'legais']
----> 2 print lista[3]

IndexError: list index out of range

Como podemos ver, ao tentar acessar um índice que esta fora da lista vai gerar a exceção (erro) de IndexError: list index out of range.

Mas e se tentarmos inserir algo na posição 3?

In [6]:
lista = ['Listas','nao sao', 'legais']
lista[3] = "mais alguem"
print lista
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-6-4ff4fea372b8> in <module>()
      1 lista = ['Listas','nao sao', 'legais']
----> 2 lista[3] = "mais alguem"
      3 print lista

IndexError: list assignment index out of range

Deu erro novamente... Mas e como inserimos valores na lista?

Inserindo novos valores em uma lista

Em python uma lista tem alguns métodos (funções) associados a ela. Alguns destes métodos são para inserir novos elementos na lista. Sempre que quisermos inserir um valor no final da lista podemos utilizar o método append().

Exemplo:

In [7]:
numerosDaMega = [6, 7, 33, 3, 5]
print numerosDaMega

#aqui adicionamos mais um valor ao fim
numerosDaMega.append(22)
print numerosDaMega

#se você jogar estes numeros, quero minha parte do premio =D 
[6, 7, 33, 3, 5]
[6, 7, 33, 3, 5, 22]

Viu que interessante? Agora podemos ir adicionando números à nossa lista usando o append. Mas e se eu não quiser inserir no fim da lista?

Existe o método .insert(indice, valor) para inserção baseado em índice, este método recebe o índice de onde vai ser inserido o valor e o valor.

Exemplo:

In [8]:
numerosDaMega = [6, 7, 33, 3, 5]
print numerosDaMega

#aqui adicionamos o 22 no ínicio
numerosDaMega.insert(0,22)
print numerosDaMega

#aqui adicionamos o 4 na segunda posição.
numerosDaMega.insert(1,4)
print numerosDaMega
[6, 7, 33, 3, 5]
[22, 6, 7, 33, 3, 5]
[22, 4, 6, 7, 33, 3, 5]

Com o método insert podemos inserir em qualquer posição da lista. Mas e se eu quiser remover alguem da lista?

Removendo valores da lista

Para remover um valor de uma lista usamos o método .remove(valor). Este método remove a primeira ocorrencia do valor que passamos para ele.

Exemplo:

In [9]:
valores = [33.5, 55.0, .05, 55.0]
print valores
valores.remove(55.0)
print valores
[33.5, 55.0, 0.05, 55.0]
[33.5, 0.05, 55.0]

Listas e laços de repetição

Como já foi dito antes, listas e laços de repetição combinam muito bem.

Esta é uma combinação que permite, por exemplo, ler 5 numeros e calcular a média deles só depois de toda a leitura. Pois não perdemos estes números durante a leitura graças a lista.

Exemplo:

In [11]:
lista = [] #criamos uma lista vazia.

#le os números
for i in range(0,5):
    numero = int(raw_input("digite o número " + str(i) + " da lista:" ))
    lista.append(numero)
    
#Depois da leitura, os números estao armazenados na lista
print lista

#Agora vamos acessar cada valor individualmente e calcular a média
media = 0
for i in range(0,5):
    media = media + lista[i] #observe que aqui usamos o contador i do for como indice para pegar cada valor da lista

media = media / 5   
print "media dos valores = " + str(media)
digite o número 0 da lista:5
digite o número 1 da lista:6
digite o número 2 da lista:9
digite o número 3 da lista:8
digite o número 4 da lista:5
[5, 6, 9, 8, 5]
media dos valores = 6

Com listas numca mais perderemos nossos valores e desta forma podemos separar nossa lógica em pequenos pedaços. Mas e se eu quiser ler quantos números o usuário quiser informar, e depois calcular a média?

Bom, como já sabemos, neste caso é teremos usar um while.

Exemplo:

In [12]:
lista = []
comando = 0
while comando != "sair":
    comando = raw_input("digite sair ou um número");
    if comando == "sair":
        continue
    
    numero = int(comando)
    lista.append(numero)
    
print lista

media = 0
for i in range(0, len(lista)):
    media = media + lista[i] #observe que aqui usamos o contador i do for como indice para pegar cada valor da lista

media = media /  len(lista)   
print "media dos valores = " + str(media)
    
digite sair ou um número1
digite sair ou um número5
digite sair ou um número6
digite sair ou um número2
digite sair ou um número5
digite sair ou um número5
digite sair ou um número5
digite sair ou um número5
digite sair ou um número5
digite sair ou um número54
digite sair ou um número4
digite sair ou um númerosair
[1, 5, 6, 2, 5, 5, 5, 5, 5, 54, 4]
media dos valores = 8

Com este código o usuário pode informar quantos números quiser e ao digitar sair ele para de ler números para lista. Depois disto, como agora já sabemos a quantidade de elementos da lista... Pera ai, sabemos? Sim, podemos chegar o tamanho de uma lista a qualquer momento usando a função len() do python. Esta função retorna a quantidade de elementos da lista =), dispensando, desta forma, a necessidade de um contador. Observe que no código anterior tem dois usos do len().

E antes de encerrar esta seção, o for tem uma carta na manga. Você já chamou a função range que usamos no for sozinha?

Se não, veja o que ele mostra ao imprimirmos o seu resultado

In [13]:
print range(0, 20)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

O retorno da função range retorna uma lista. Pasmem! hehe.

Mas então, será que eu posso passar uma lista ali? e o que acontece com ela?

Na realidade o for recebe uma lista como entrada, até então estamos dando como entrada uma lista de contagem, e para cada um dos elementos desta lista o seu "contador" recebe um novo valor a cada nova iteração. Mas esta lista pode ser de qualquer coisa.

Exemplo:

In [14]:
pessoas = ["luis", "maria", "claudia", "joão", "roberto"]

for p in pessoas:
    print p
luis
maria
claudia
joão
roberto

Viu que interessante? Temos uma lista de strings, que guarda em cada posição um nome, e ao passarmos esta lista para o for no lugar da função range() ele itera em cada um dos nomes da lista.

Mas e se eu quiser mostrar estes nomes ordenados?

Ordenando uma lista

Para ordenar uma lista é só chamarmos seu método .sort() este método ordena, por padrão, de forma crescente. Entretanto pode-se passar para ele uma função explicando como deve ser feita a ordenação. Não iremos cobrir isso neste capítulo.

Exemplo:

In [15]:
pessoas = ["luis", "maria", "claudia", "joão", "roberto"]

pessoas.sort()

for p in pessoas:
    print p
claudia
joão
luis
maria
roberto

Copia de listas

Em alguns momentos, será necessário copiar uma lista para outra para modificar a nova lista sem perder a original. O comportamento mais instintivo que temos é fazer o seguinte:

In [16]:
lista1 =  ["gato", "cachorro", "vaca", "galinha"]
lista2 = lista1

print lista1
print lista2
['gato', 'cachorro', 'vaca', 'galinha']
['gato', 'cachorro', 'vaca', 'galinha']

Pareque que a lista foi copiada né? Mas obeserve o que acontece ao modificarmos uma posição da lista2.

In [17]:
lista1 =  ["gato", "cachorro", "vaca", "galinha"]
lista2 = lista1

lista2[1] = "Camelo"

print lista1
print lista2
['gato', 'Camelo', 'vaca', 'galinha']
['gato', 'Camelo', 'vaca', 'galinha']

Mudou nas duas listas? Mas como, isso não é uma copia!!! Na verdade o que acontece é que ao atribuirmos uma lista a outra, ambas apontam para os mesmos dados, então se mudarmos numa lista vai mudar na outra também.

Mas eu quero copiar! Como que faz?

Para realizar a copia é muito parecido com o que fizemos. Mas devemos dizer que queremos fatiar (já vamos falar mais em detalhes disto) a lista em um pedaço inteiro e colocar ele para dentro da lista nova.

Exemplo:

In [18]:
lista1 =  ["gato", "cachorro", "vaca", "galinha"]
lista2 = lista1[:]

lista2[1] = "Camelo"

print lista1
print lista2
['gato', 'cachorro', 'vaca', 'galinha']
['gato', 'Camelo', 'vaca', 'galinha']

Agora temos uma cópia. O que mudou? apenas isto -> lista2 = lista1[:]

Mas o que aqueles dois pontos([:]) dentro dos colchetes significam? Significam que estamos fatiando a lista, porem pegando tudo que esta nela. A seguir isso fica mais claro.

Fatiamento de listas

O fatiamento de listas é uma forma de pegar apenas uma parte de uma determinada lista. Por exemplo, queremos pegar apenas uma parte do ínicio da lista ou do meio. Para realizar o fatiamento utilizamos os dois pontos dentro do colchetes da lista. A sintaxe é a seguinte lista[inicioFatiamento:fimDoFatiamento], observe que tanto o início quanto o fim são indices.

Exemplo:

In [19]:
lista = range(10,100,10) #cria uma lista com multiplos de 10

listaFatiada = lista[3:6]

print lista
print listaFatiada
[10, 20, 30, 40, 50, 60, 70, 80, 90]
[40, 50, 60]

Viu que baca, podemos pegar uma sub-lista de qualquer lista usando este recuros. Se não informarmos o início ou o fim do fatiamento por padrão ele vai pegar do início ou fim.

Exemplo:

In [20]:
lista = range(10,100,10) #cria uma lista com multiplos de 10

listaFatiada1 = lista[:6] #vai pegar tudo do inicio até o 6
listaFatiada2 = lista[2:] #vai pegar tudo do 1 até o fim

print lista
print listaFatiada1
print listaFatiada2
[10, 20, 30, 40, 50, 60, 70, 80, 90]
[10, 20, 30, 40, 50, 60]
[30, 40, 50, 60, 70, 80, 90]

Se não infromarmos o início nem o fim do fatiamento o resultado é toda a lista. E agora deve fazer mais sentido do pq temos que usar os dois pontos para copiar uma lista.

Agora, vamos aos exercícos :)

In [ ]: