MAC2166 - Introdução à Computação

28/04/2014 - Aula 8

Listas - estruturas sequenciais indexadas

Em Python, podemos manipular listas. Uma lista é uma sequência de valores. Os valores em uma lista são chamados de elementos ou itens.

O modo mais simples de se criar uma lista é envolver seus elementos com um par de chaves. O tipo de uma lista é list.

In [1]:
 
lista1 = [4, 2, 9]     # cria uma lista com três números inteiros, os números 4, 2 e 9
print(type(lista1))    
print("O conteúdo da lista é:", lista1)
print("A quantidade de elementos da lista é:", len(lista1))
<class 'list'>
O conteúdo da lista é: [4, 2, 9]
A quantidade de elementos da lista é: 3

Para obter o comprimento de uma lista (ou seja, o número de elementos que a lista possui) usamos a função len() (de length), como mostrado no exemplo acima.

[] denota uma lista vazia, ou seja, uma lista que não contém nenhum elemento. O comprimento de uma lista que não contém nenhum elemento é 0.

In [2]:
 
lista2 = []     # cria uma lista vazia, ou seja com nenhum elemento dentro dela
print("O conteúdo da lista é:", lista2)
print("A quantidade de elementos da lista é:", len(lista2))
O conteúdo da lista é: []
A quantidade de elementos da lista é: 0

Usando o operador * conseguimos criar rapidamente listas de um determinado comprimento contendo elementos iguais. Veja os exemplos.

In [4]:
 
lista3 = [3] * 10   # criar uma lista contendo 10 elementos, todos de valor 3
tamanho = len(lista3) 
print("Lista com",len(lista3),"elementos de valor 3:",lista3)
print()
lista3 = [1,2,3] * 5 
print("Lista com 5 subsequências repetidas:",lista3)
Lista com 10 elementos de valor 3: [3, 3, 3, 3, 3, 3, 3, 3, 3, 3]

Lista com 5 subsequências repetidas: [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]

Os elementos em uma lista não precisam ser todos de um mesmo tipo, como mostra o exemplo a seguir:

In [5]:
 
lista4 = ["Hello", 2, 5.6, "World", 15]
print("Uma lista com elementos de diferentes tipos:", lista4)
Uma lista com elementos de diferentes tipos: ['Hello', 2, 5.6, 'World', 15]

Usamos l[i] para nos referir à posição de número (= índice) i uma lista l, sendo que a primeira posição de uma lista é a de índice 0, a segunda é a de índice 1, e assim por diante, até a última posição da lista - que tem índice len(l)-1. Veja os exemplos a seguir:

In [6]:
 
lista5 = [10, 20, 30, 40, 50]
print(lista5[0])      # mostra o valor do primeiro elemento da lista
print(lista5[2])
print(lista5[4])      # mostra o valor do último elemento da lista
print(lista5[len(lista5)-1])   # também mostra o valor do último elemento da lista
10
30
50
50

Podemos usar números negativos como índices para acessar as posições de uma lista na ordem reversa, ou seja, do fim para o início. O índice -1 se refere a última posição da lista, o -2 se refere à penúltima posição, e assim por diante.

In [7]:
 
lista5 = [10, 20, 30, 40, 50]
print(lista5[-1])             # mostra o valor do último elemento da lista
print(lista5[-len(lista5)])   # mostra o valor do primeiro elemento da lista
50
10

Também é possível modificar o valor de uma posição específica da lista:

In [8]:
 
lista6 = [10, 20, 30]
print(lista6)
lista6[0] = 5      # altera o valor da primeira posição da lista
lista6[-1] //= 2   # altera o valor da última posição da lista
print(lista6)
[10, 20, 30]
[5, 20, 15]

Quanto tentamos acessar uma posição que não existe na lista, um erro de execução list index out of range é gerado:

In [9]:
 
lista7 = [10, 20]
print(lista7[2])   # tenta exibir o valor de uma posição que não existe na lista
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-9-65b8d9d88670> in <module>()
      1 lista7 = [10, 20]
----> 2 print(lista7[2])   # tenta exibir o valor de uma posição que não existe na lista

IndexError: list index out of range

Podemos usar a função append() para acrescentar novos elementos em uma lista. Para acrescenter o elemento x ao final de uma lista l, fazemos l.append(x). Veja os exemplos a seguir:

In [10]:
 
lista8 = [40]
print("Estado inicial da lista: ", lista8)
lista8.append(10)
print("Estado da lista depois da primeira inclusão de um novo elemento: ", lista8)
lista8.append(30)
print("Estado da lista depois da segunda inclusão de um novo elemento: ", lista8)
Estado inicial da lista:  [40]
Estado da lista depois da primeira inclusão de um novo elemento:  [40, 10]
Estado da lista depois da segunda inclusão de um novo elemento:  [40, 10, 30]

Embora os elementos de uma lista também possam ser percorridos por meio de um laço tradicional (os que vimos nas aulas anteriores), existe um tipo de laço for especial para percorrer todos os elementos de lista, começando do seu início para o fim. A estrutura desse laço é

for elemento in lista:

onde elemento é o nome da variável que receberá um elemento da lista e lista é uma lista de elementos. Exemplo:

In [11]:
 
lista9 = [10, 20, 30, 40]
soma = 0
for numero in lista9:
    print(numero)
    soma += numero
print("A soma é", soma)
10
20
30
40
A soma é 100

Finalmente, o operador in nos permite verificar se um dado valor está em uma lista. A expressão

valor in lista

devolve True se valor for um elemento de lista, e False no caso contrário.

In [12]:
 
lista10 = [0,2,4,6,8,10]
print(lista10)
if 4 in lista10:
    print("O valor 4 está na lista.")
if 3 not in lista10:
    print("O valor 3 não está na lista.")
[0, 2, 4, 6, 8, 10]
O valor 4 está na lista.
O valor 3 não está na lista.

Problema 15

Dados n > 0 e uma sequência com n números reais, imprimi-los na ordem inversa à da leitura.

Obs.: Este problema corresponde ao exercício 1 da lista de exercícios sobre vetores.

In [ ]:
 
print ("Lê n inteiros e imprime-os em ordem reversa")
n = int(input("Digite n: "))
cont = 0
seq = []  # cria uma lista vazia
 
while cont < n:
    num = int(input("Digite um número da sequência: "))
    seq.append(num)   # coloca num no final da lista
    cont += 1
 
print("Sequência original: ", seq)
 
 
print("Solução 1: usando índices decrescentes")
cont = n-1
while cont >= 0:
    print (seq[cont], end=' ')
    cont -= 1
print ()
 
# ou ainda, usando índices negativos
print("Solução 2: usando índices negativos")
cont = -1
while cont >= -n:
    print (seq[cont], end=' ')
    cont -= 1
print()

Além do uso de uma lista e da função append() para adicionar elementos nela, uma novidade que aparece na solução acima é o uso da função print() com o parâmetro end. Quando usamos a função print sem passar um valor para o parâmetro end, o comportamento da função é escrever na saída os parâmetros que recebeu como entrada e pular e linha. Veja a saída gerada pelo exemplo abaixo:

In [ ]:
 
print("Esta mensagem aparece na primeira linha da saída...")   # Linha 1
print("Enquanto essa aparece na segunda!")                     # Linha 2
print()   # Só quebra a linha, sem mostrar mais nada           # Linha 3
print()                                                        # Linha 4
print("E esta aqui aparece só na quinta linha.")               # Linha 5

Às vezes, queremos que as mensagens ou os valores escrito usando chamadas consecutivas à função print sejam escritos em uma mesma linha. Para que isso seja possível, precisamos informar à função print que ela não deve pular de linha após escrever na saída os valores. E é para isso que o parâmetro end server: para indicar à função print o que ela deve escrever em substituição à quebra de linha. No caso da solução do Problema 15, a quebra de linha foi substituída por um espaço em branco. Veja outros exemplos abaixo:

In [ ]:
 
print("A parte 1 da mensagem", end = " ")     # Este print não quebra a linha,
print("e a parte 2 da mensagem", end = " ")   # e este aqui também não!
print("estão todas na mesma linha!")          # Mas este print quebra a linha.
print("Mas esta parte vai ficar sozinha!")

Observação: no Python, é possível usar a função reverse() de um objeto do tipo List que inverte a ordem dos elementos de uma lista. Mas é preciso ter cuidado ao usar essa função, por que ela modifica a lista a partir da qual ela foi chamada. Além disso, é muito importante saber percorrer uma lista da forma tradicional, em ordem "normal" ou inversa, usando um laço while ou for, já que muitas linguagens não possuem uma função equivalente à reverse().

Usando a função reverse(), a solução do Problema 15 fica como a mostrada a seguir:

In [ ]:
 
print ("Lê n inteiros e imprime-os em ordem reversa")
n = int(input("Digite n: "))
cont = 0
seq = []  # cria uma lista vazia
 
while cont < n:
    num = int(input("Digite um número da sequência: "))
    seq.append(num)   # coloca num no final da lista
    cont += 1
 
print("Sequência original: ", seq)
 
# ou ainda, usando a função reverse()
seq.reverse()         # inverte a ordem dos elementos da lista
print("Solução 3: usando a função reverse()")
print(seq)
 

Problema 16

Dados n > 0 lançamentos de uma roleta (números entre 0 e 36), calcular a frequência de cada número.

In [ ]:
 
print ("Frequência relativa de n lançamentos de uma roleta")
n = int(input("Digite n: "))
cont = 0
seq = [0] * 37   # cria uma lista de 37 posições com zeros
print(seq)
 
while cont < n:
    cont += 1
    num  = int(input("Digite o resultado do lançamento %d: "%(cont)))
    seq[num] += 1
 
i = 0
for freq in seq:
    print("frequência do número %d = %5.2f"%(i, freq/n))
    i += 1
 
# ou ainda, usando as funções range() e len()
print("Outra solução")
for i in range(len(seq)):
    print ("frequência do número %d = %5.2f"%(i, seq[i]/n))
 

Problema 17

Dada uma sequência de n > 0 números reais, imprimi-los eliminando as repetições.

Solução 1 (usando while para percorrer os elementos da lista)

In [ ]:
 
print("Ler uma sequência de n números e imprimir sem repetições")
n = int(input("Digite n: "))
cont = 0
seq = []
 
# primeira solução
print ("Solução 1: procurando varrendo índices")
 
while cont < n:
    cont += 1
    num = float(input("Digite o elemento %d da seq: "%(cont)))
    # procura na lista varrendo índices
    ind = 0
    achei = False
    while ind < len(seq) and not achei:
        if num == seq[ind]:
            achei = True
        ind += 1
    if not achei:
        seq.append(num)
print(seq)

A solução para o Problema 17 se baseia na idea de só armazenar na lista um número digitado pelo usuário se ele ainda não estiver na lista. Assim, cada valor diferente pertencente à sequência de números só aparecerá na lista uma única vez.

Solução 2 (usando for para percorrer os elementos da lista)

In [ ]:
 
print("Ler uma sequência de n números e imprimir sem repetições")
n = int(input("Digite n: "))
cont = 0
seq = []
 
# segunda solução
# OBS: o for vai sempre até o fim!
print ("Solução 2: procurando usando varredura com for")
 
while cont < n:
    cont += 1
    num = float(input("Digite o elemento %d da seq: "%(cont)))
    # procura na lista usando for
    achei = False
    for elemento in seq:
        if num == elemento:
            achei = True
    if not achei:
        seq.append(num)
print(seq)

Solução 3 (usando o operador in para verificar se um dado valor está na lista)

In [ ]:
 
print("Ler uma sequência de n números e imprimir sem repetições")
n = int(input("Digite n: "))
cont = 0
seq = []
 
# terceira solução: usando mais Python
print ("Solução 3: perguntando ao invés de procurar")
 
while cont < n:
    cont += 1
    num = float(input("Digite o número %d da seq: "%(cont)))
    if num not in seq:
        seq.append(num)
print(seq)

Problema Extra

Dados dois números naturais m e n e duas sequências ordenadas com m > 0 e n > 0 números inteiros, criar uma nova lista contendo a sequência ordenada com todos os elementos das sequências originais sem repetição.

Obs.: Este problema corresponde ao exercício 8 da lista de exercícios sobre vetores.

In [ ]:
 
# Lê os elementos da primeira sequencia 
m = int(input("Digite m: "))
cont1 = 0
seq1 = []
while cont1 < m:
    cont1 += 1
    num = int(input("Digite o número %d da sequencia 1: "%(cont1)))
    seq1.append(num)
    
print()
 
# Lê os elementos da segunda sequencia 
n = int(input("Digite n: "))
cont2 = 0
seq2 = []
while cont2 < n:
    cont2 += 1
    num = int(input("Digite o número %d da sequencia 2: "%(cont2)))
    seq2.append(num)
 
# Cria a sequencia ordenada a partir das duas outras
seq_ordenada = []    
 
cont1 = 0
cont2 = 0
 
# Intercala os elementos de forma ordenada até que uma das listas chegue ao fim
while cont1 < m and cont2 < n:
    if seq1[cont1] <= seq2[cont2]:
        # Só insere se não for repetido
        if len(seq_ordenada) == 0 or seq1[cont1] != seq_ordenada[-1]:
            seq_ordenada.append(seq1[cont1])
        cont1 += 1
    else:
        if len(seq_ordenada) == 0 or seq2[cont2] != seq_ordenada[-1]:
            seq_ordenada.append(seq2[cont2])
        cont2 += 1
 
# Inclui na lista ordenada os elementos restantes da lista que não foi 
# percorrida até o fim no laço anterior
while cont1 < m:
    if len(seq_ordenada) == 0 or seq1[cont1] != seq_ordenada[-1]:
        seq_ordenada.append(seq1[cont1])
    cont1 += 1
    
while cont2 < n:
    if len(seq_ordenada) == 0 or seq2[cont2] != seq_ordenada[-1]:
        seq_ordenada.append(seq2[cont2])
    cont2 += 1
    
print(seq_ordenada)
 

Tópicos vistos na aula 8

Sobre Listas - estruturas sequenciais indexadas:

  • Como criar e acessar o conteúdo de uma lista
  • Função len() - para obter o número de elementos de uma lista
  • Função append() - para adicionar um elemento no final da lista
  • Comando for elem in lista para percorrer os elementos de uma lista
  • Comando in para verificar se um valor está na lista

Referências e outros materiais para estudo