Pular para o conteúdo principal

03 Estruturas de dados

Estruturas de dados: listas

Revisão

Antes de começar seria bom fazer uma revisão e reforçar alguns conceitos.

Na aula passada Vimos rcondicionais e repeticções

Condicionais

Com expressões condicionais, podemos selecionar o que é executado. O mecanismo básico é a expressão if.

In [1]:
condição = True
if condição:
    print("Executado porque a condição é verdadeira")
Executado porque a condição é verdadeira
In [2]:
condição = False
if condição:
    print("Executado porque a condição é verdadeira")
    
# Nada foi impresso porque a condição é falsa

Existe uma outra forma da expressão if. Se a condição for verdadeira, funciona igual. Caso contrário executa a parte do else:

In [4]:
condição = False
if condição:
    print("Executando porque a condição é verdadeira")
else:
    print("Executando porque a condição é FALSA")
Executando porque a condição é FALSA

Algumas vezes queremos escolher mais de uma condição. Para isso temos o elif.

Com isso o if vai verificar cada condição sequencialmente. Quando alguma das condições for verdadeira (True).

In [5]:
cond1 = False
cond2 = False
cond3 = False
cond4 = True

if cond1:
    print("cond1")
elif cond2:
    print("cond2")
elif cond3:
    print("cond3")
elif cond4:
    print("cond4")
else: 
    print("Nada foi verdadeiro")
cond4
Detalhe importante:

Até este momento associei if a expressões condicionais. Este é o jeito mais seguro e comum de usar. Na verdade, if (e elif) considera algo verdadeiro se não foi 0, False ou estrutura de dados vazia (veremos estruturas de dados hoje). O resto é verdade

In [6]:
if 0:
    print("TRUE")
else:
    print("FALSE")
    
FALSE

Repetições

Mostramos como se repete alguma operação com Python. O mecanismo mais básico é a expressão while:

while condição:
    # Executar este bloco
    # enquanto condição for verdadeira

Enquanto a condição for verdadeira, o bloco vai ser executado. Por isso é importante que se faça algo para tornar a condição falsa de modo a interromper o laço.

In [7]:
i = 1
while i <= 5:
    print(i)
    i = i + 1
1
2
3
4
5

Algo que não foi falado é que você pode interromper em qualquer lugar a execução do laço com a expressão break.

In [8]:
i = 1
while True:
    if i > 5:
        break
    print(i)
    i = i + 1
1
2
3
4
5

Em várias linguagens de programação existem mecanismos para se criar laços onde o teste está no final, de modo que o corpo do laço seja executado pelo menos uma vez. Em C, isso seria os laços do - while. Não existe nada parecido em Python. Mas isso não é necessário, basta usar o break

In [9]:
i = 1
while True:
    print(i)
    i = i + 1
    if i > 5: break
1
2
3
4
5

Muitas vezes você não quer sair do laço mas simplesmente ir para a próxima iteração. Para isso existe a expressão continue

In [10]:
i = 0
while i < 5:
    i = i + 1
    if i == 3:
        continue
    print(i)
    
1
2
4
5

Estrtuturas de dados

Até este momento, vimos a criação de variáveis que armazenavam números (inteiros ou de ponto flutuante) ou strings. E se quisermos trabalhar com uma quantidade variável de números (ou strings)? Teríamos que criar mais de uma variável. Isso não apenas é chato mas bem limitante. Para isso existem as estruturas de dados que são elementos do Python que permitem armazenar e gerenciar mais de um objeto (números, strings, ou qualquer outra coisa).

O strings são um caso especial pois são uma coleção de caracteres. Mas em geral os strings são tratados como um elemento único.

Listas

As listas são um tipo de variável que permitem armazenar vários valores acessados por um índice. A lista pode conter 0 ou mais elementos de qualquer tipo, inclusive outras listas (e outras estruturas de dados).

Assim como os caracteres de uma string, as listas são indexadas por números inteiros começando em 0.

In [11]:
# Uma lista vazia
L = []
print(len(L))
L
0
Out[11]:
[]
In [12]:
Z = [15, 8, 9]
print(Z[0])
print(Z[1])
print(Z[2])
15
8
9
In [13]:
# Erro se o índice não existir
Z[3]
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
/tmp/ipykernel_3105/1148129213.py in <module>
      1 # Erro se o índice não existir
----> 2 Z[3]

IndexError: list index out of range
In [14]:
# É possível mudar o valor das variáveis
Z[1] = 123
Z
Out[14]:
[15, 123, 9]
In [15]:
# Programa para cálculo da média de 5 notas
notas = [6, 7, 5, 8, 9]
soma = 0
i = 0
while i < 5:
    soma += notas[i]
    i += 1
print(f"Média: {soma/i:4.1f}")
    
Média:  7.0
In [17]:
# Versão do programa onde o professor pode entrar com as notas
notas = [0,0,0,0,0]
soma = 0
i = 0
while i < 5:
    notas[i] = float(input(f"Nota {i}: "))
    soma += notas[i]
    i += 1
print(f"Média: {soma/i:4.1f}")
Nota 0: 5
Nota 1: 6
Nota 2: 8
Nota 3: 7
Nota 4: 9
Média:  7.0

Exercício 1

Modifique os programas acima para ler 7 notas no lugar de 5.

Cópia e fatiamento de listas

In [18]:
L = [1,2,3,4,5]
V = L
In [19]:
L
Out[19]:
[1, 2, 3, 4, 5]
In [20]:
V
Out[20]:
[1, 2, 3, 4, 5]
In [21]:
V[0] = 999
V
Out[21]:
[999, 2, 3, 4, 5]
In [22]:
L
Out[22]:
[999, 2, 3, 4, 5]
In [23]:
L = [1,2,3,4,5]
V = L[:]
In [24]:
V[0] = 999
In [25]:
V
Out[25]:
[999, 2, 3, 4, 5]
In [26]:
L
Out[26]:
[1, 2, 3, 4, 5]

Fatiamento de listas

Lembra do fatiamento de strings? Listas funcionam de maneira bem parecida

In [27]:
s = "ABCDEF"
s[:]
Out[27]:
'ABCDEF'
In [28]:
L = [1,2,3,4,5]
In [29]:
L[0:5]
Out[29]:
[1, 2, 3, 4, 5]
In [30]:
L[0:3]
Out[30]:
[1, 2, 3]
In [31]:
L[2:]
Out[31]:
[3, 4, 5]
In [32]:
L[:2]
Out[32]:
[1, 2]
In [33]:
L[1:4]
Out[33]:
[2, 3, 4]

Tamanho de listas

A função len retorna o número de elementos de uma lista.

In [34]:
len([])
Out[34]:
0
In [35]:
len([1])
Out[35]:
1
In [36]:
len([1,2,3])
Out[36]:
3
In [37]:
len(L)
Out[37]:
5

Lembra do programa para tirar a média? Com len dá para melhorar!

In [38]:
# Programa para cálculo da média de 5 notas
notas = [6, 7, 5, 8, 9]

soma = 0
i = 0
while i < len(notas):
    soma += notas[i]
    i += 1
print(f"Média: {soma/i:4.1f}")
Média:  7.0

Adicionando elementos a uma lista

As listas podem crescer de acordo com a conveniência. Para adicionar um elemento a uma lista, basta usar o método append.

Um método parece com uma função (como len) mas está associado ao objeto. Em python, as variáveis armazenam objetos que podem ser números, strings, listas, e um monte de outras coisas.

Funções recebem (entre parênteses) objetos e retornam um outro objeto. Mas métodos estão associados a estes objetos, são parte intrínseca dos objetos. No final do curso vamos ver em detalhes como isso funciona. Mas por enquanto, vamos aprender a utilizá-los.

Dica de como ver os métodos disponíveis

Se você tiver alguma variável, digite seu nome, digite ponto (sem espaço!) e pressione a tecla TAB. Vai aparecer uma lista com os métodos disponíveis para a variável.

In [39]:
x = []
In [40]:
L = []
In [41]:
L.append("a")
In [42]:
L
Out[42]:
['a']
In [43]:
L.append("b")
In [44]:
L
Out[44]:
['a', 'b']
In [45]:
L.append("c")
In [46]:
len(L)
Out[46]:
3
In [47]:
L.append([1,2,3])
In [48]:
L
Out[48]:
['a', 'b', 'c', [1, 2, 3]]
In [49]:
# Programa para adicionar números a uma lista
L = []
while True:
    n = int(input("Digite um número (0 sai): "))
    if n == 0:
        break
    L.append(n)
L
Digite um número (0 sai): 5
Digite um número (0 sai): 3
Digite um número (0 sai): 9
Digite um número (0 sai): 6
Digite um número (0 sai): 11
Digite um número (0 sai): 0
Out[49]:
[5, 3, 9, 6, 11]
Vocês se lembram da concatenação de strings?

A mesma coisa é possível com listas. Apenas com listas!

In [50]:
[1,2,3] + [4]
Out[50]:
[1, 2, 3, 4]
In [51]:
[1,2,3] + [4,5,6]
Out[51]:
[1, 2, 3, 4, 5, 6]
In [52]:
[1,2,3] + 4
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/tmp/ipykernel_3105/2703596034.py in <module>
----> 1 [1,2,3] + 4

TypeError: can only concatenate list (not "int") to list

O método append adiciona elementos novos à lista. Já o método extend funciona como a concatenação acima.

In [53]:
L = [1,2,3]
In [54]:
L.append(4)
In [55]:
L
Out[55]:
[1, 2, 3, 4]
In [56]:
L.append([5,6])
In [57]:
L
Out[57]:
[1, 2, 3, 4, [5, 6]]
In [58]:
L.extend([7,8])
In [59]:
L
Out[59]:
[1, 2, 3, 4, [5, 6], 7, 8]

Exercício 2

Reescreva o programa para calcular médias de modo que o professor primeiro entra com o número de notas e em seguida o programa lê este número de notas e calcula a média.

Exercício 3

Faça um programa que percorra duas listas inteiras e gere uma terceira sem elementos repetidos

Remoção de elementos da lista

Algumas vezes você quer remover elementos da lista. Isso é feito com a instrução del:

In [60]:
L = [1,2,3]
In [61]:
del L[1]
L
Out[61]:
[1, 3]
In [62]:
L = list(range(101))
In [63]:
del L[10:90]
In [64]:
L
Out[64]:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100]
In [65]:
x = list(range(11))
In [66]:
x.pop(5)
Out[66]:
5
In [67]:
x
Out[67]:
[0, 1, 2, 3, 4, 6, 7, 8, 9, 10]

Filas

Uma lista pode ser utilizada como uma fila. Numa fila as pessoas entram no final e saem no começo. Na literatura a fila é conhecida como FIFO (First In First Out, primeiro que entra primeiro que sai). É uma estrutura de dados muito útil em diversas situações.

Como exemplo vamos simular uma fila de banco:

In [152]:
# Simulação de fila de banco:
último = 10
fila = list(range(1, último + 1))
while True:
    print(f"\nExistem {len(fila)} clientes na fila")
    print(f"Fila atual: {fila}")
    print("Digite F para adicionar um cliente ao fim da fila, ")
    print("ou A para realizar o atendimento. S para sair.")
    operação = input("Operação (F, A ou S): ")
    if operação == "A":
        if len(fila) > 0:
            atendido = fila.pop(0)
            print(f"Cliente {atendido} atendido")
        else:
            print("Fila vazia! Nenhum cliente para atender.")
    elif operação == "F":
        último += 1 # Incrementa o ticket
        fila.append(último)
    elif operação == 'S':
        break
    else:
        print("Operação inválida. Digite apenas A, F ou S!")
Existem 10 clientes na fila
Fila atual: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Digite F para adicionar um cliente ao fim da fila, 
ou A para realizar o atendimento. S para sair.
Operação (F, A ou S): A
Cliente 1 atendido

Existem 9 clientes na fila
Fila atual: [2, 3, 4, 5, 6, 7, 8, 9, 10]
Digite F para adicionar um cliente ao fim da fila, 
ou A para realizar o atendimento. S para sair.
Operação (F, A ou S): A
Cliente 2 atendido

Existem 8 clientes na fila
Fila atual: [3, 4, 5, 6, 7, 8, 9, 10]
Digite F para adicionar um cliente ao fim da fila, 
ou A para realizar o atendimento. S para sair.
Operação (F, A ou S): F

Existem 9 clientes na fila
Fila atual: [3, 4, 5, 6, 7, 8, 9, 10, 11]
Digite F para adicionar um cliente ao fim da fila, 
ou A para realizar o atendimento. S para sair.
Operação (F, A ou S): S

Exercício 4

O que acontece quando não verificamos se a lista está vazia antes de chamar o método pop?

In [ ]:
 

Exercício 5

Altere o programa da fila de modo que se possa trabalhar com vários comandos digitados de uma só vez. No programa acima, apenas uma operação pode ser digitada por vez. Faça com que o programa aceite strings com vários comandos

Exemplo: FFFAAAS significa três chegadas de novos clientes, três atendimentos e saída do programa.

Listas como pilhas

Uma outra estrutura de dados muito importante é a pilha. Em inglês isso se chama stack. Neste tipo de estrutura, você insere elementos no final e eles saem pelo final. Na literatura, listas são conhecidas como LIFO - Last In First Out (último a entrar é o primeiro a sair).

Nesse caso, para se adicionar um elemento à pilha, usa-se o método append. Para se retirar um elemento da pilha, o método pop sem nenhum argumento (our argumento -1 que indica o último elemento).

In [156]:
# Programa para gerenciar a lavagem de pratos
prato = 5 
pilha = list(range(1,prato+1))
while True:
    print(f"\nExistem {len(pilha)} pratos na pilha")
    print(f"Pilha atual: {pilha}")
    print("Digite E para empilhar um novo prato,")
    print("ou D para desempilhar e lavar. S para sair.")
    operação = input("Operação (E, D ou S): ")
    if operação == 'D':
        if len(pilha) > 0:
            lavado = pilha.pop(-1)
            print(f"Prato {lavado} lavado")
        else:
            print("Pilha vazia, nada para lavar!")
    elif operação == 'E':
        prato += 1
        pilha.append(prato)
    elif operação == 'S':
        break
    else:
        print("Operação inválida. Digite apenas E, D ou S!")
        
Existem 5 pratos na pilha
Pilha atual: [1, 2, 3, 4, 5]
Digite E para empilhar um novo prato,
ou D para desempilhar e lavar. S para sair.
Operação (E, D ou S): D
Prato 5 lavado

Existem 4 pratos na pilha
Pilha atual: [1, 2, 3, 4]
Digite E para empilhar um novo prato,
ou D para desempilhar e lavar. S para sair.
Operação (E, D ou S): D
Prato 4 lavado

Existem 3 pratos na pilha
Pilha atual: [1, 2, 3]
Digite E para empilhar um novo prato,
ou D para desempilhar e lavar. S para sair.
Operação (E, D ou S): E

Existem 4 pratos na pilha
Pilha atual: [1, 2, 3, 6]
Digite E para empilhar um novo prato,
ou D para desempilhar e lavar. S para sair.
Operação (E, D ou S): E

Existem 5 pratos na pilha
Pilha atual: [1, 2, 3, 6, 7]
Digite E para empilhar um novo prato,
ou D para desempilhar e lavar. S para sair.
Operação (E, D ou S): E

Existem 6 pratos na pilha
Pilha atual: [1, 2, 3, 6, 7, 8]
Digite E para empilhar um novo prato,
ou D para desempilhar e lavar. S para sair.
Operação (E, D ou S): D
Prato 8 lavado

Existem 5 pratos na pilha
Pilha atual: [1, 2, 3, 6, 7]
Digite E para empilhar um novo prato,
ou D para desempilhar e lavar. S para sair.
Operação (E, D ou S): D
Prato 7 lavado

Existem 4 pratos na pilha
Pilha atual: [1, 2, 3, 6]
Digite E para empilhar um novo prato,
ou D para desempilhar e lavar. S para sair.
Operação (E, D ou S): D
Prato 6 lavado

Existem 3 pratos na pilha
Pilha atual: [1, 2, 3]
Digite E para empilhar um novo prato,
ou D para desempilhar e lavar. S para sair.
Operação (E, D ou S): D
Prato 3 lavado

Existem 2 pratos na pilha
Pilha atual: [1, 2]
Digite E para empilhar um novo prato,
ou D para desempilhar e lavar. S para sair.
Operação (E, D ou S): D
Prato 2 lavado

Existem 1 pratos na pilha
Pilha atual: [1]
Digite E para empilhar um novo prato,
ou D para desempilhar e lavar. S para sair.
Operação (E, D ou S): D
Prato 1 lavado

Existem 0 pratos na pilha
Pilha atual: []
Digite E para empilhar um novo prato,
ou D para desempilhar e lavar. S para sair.
Operação (E, D ou S): D
Pilha vazia, nada para lavar!

Existem 0 pratos na pilha
Pilha atual: []
Digite E para empilhar um novo prato,
ou D para desempilhar e lavar. S para sair.
Operação (E, D ou S): D
Pilha vazia, nada para lavar!

Existem 0 pratos na pilha
Pilha atual: []
Digite E para empilhar um novo prato,
ou D para desempilhar e lavar. S para sair.
Operação (E, D ou S): E

Existem 1 pratos na pilha
Pilha atual: [9]
Digite E para empilhar um novo prato,
ou D para desempilhar e lavar. S para sair.
Operação (E, D ou S): D
Prato 9 lavado

Existem 0 pratos na pilha
Pilha atual: []
Digite E para empilhar um novo prato,
ou D para desempilhar e lavar. S para sair.
Operação (E, D ou S): E

Existem 1 pratos na pilha
Pilha atual: [10]
Digite E para empilhar um novo prato,
ou D para desempilhar e lavar. S para sair.
Operação (E, D ou S): E

Existem 2 pratos na pilha
Pilha atual: [10, 11]
Digite E para empilhar um novo prato,
ou D para desempilhar e lavar. S para sair.
Operação (E, D ou S): D
Prato 11 lavado

Existem 1 pratos na pilha
Pilha atual: [10]
Digite E para empilhar um novo prato,
ou D para desempilhar e lavar. S para sair.
Operação (E, D ou S): D
Prato 10 lavado

Existem 0 pratos na pilha
Pilha atual: []
Digite E para empilhar um novo prato,
ou D para desempilhar e lavar. S para sair.
Operação (E, D ou S): D
Pilha vazia, nada para lavar!

Existem 0 pratos na pilha
Pilha atual: []
Digite E para empilhar um novo prato,
ou D para desempilhar e lavar. S para sair.
Operação (E, D ou S): S

Exercício 6

Faça um programa que leia uma expressão com parênteses. Usando pilhas, verifique se os parênteses foram abertos e fechados na ordem correta. Exemplo:

  • (()) OK
  • ()()(()()) OK
  • ()) Erro

Pesquisando

Uma outra operação importante é pésquisar uma lista e verificar se um elemento é parte dela.

In [160]:
L = [15, 7, 27, 39]
p = int(input("Digite o valor a procurar: "))
achou = False
i = 0
while i < len(L):
    if L[i] == p:
        achou = True
        break
    i += 1
if achou:
    print(f"{p} foi encontrado na posição {i}.")
else:
    print(f"{p} não foi encontrado na lista.")
Digite o valor a procurar: 39
39 foi encontrado na posição 3.

Exercício 7

Modifique o programa de modo que realize a mesma tarefa sem usar a variável achou. Dica: observe a condição de saída do while.

In [ ]:
 

Exercício 8

Modifique o exemplo para pesquisar dois valores. Em vez de apenas p, leia outro valor v que também será procurado. Na impressão, indique qual dos dois valores foi encontrado primeiro.

Usando for

Para realizar repetições temos usado a instrução while. Repare que muitas vezes a gente quer percorrer uma lista ou um range de números. Isso é tão comum que o python fornece uma instrução de repetição para estes casos: `for.

In [68]:
L = [8,9,15]
for e in L:
    print(e)
8
9
15

No exemplo anterior, em cada iteração do laço for, o valor e assume um valor da lista L de maneira sequencial.

O código acima é equivalente ao código a seguir que usa while:

In [69]:
L = [8,9,15]
i = 0
while i < len(L):
    e = L[i]
    print(e)
    i = i + 1
8
9
15

As instruções break e continue funcionam da mesma maneira no laço for.

In [70]:
# Programa de busca
L = [7,9,10,12]
p = int(input("Digite um número a pesquisar: "))
for e in L:
    if e == p:
        print("Elemento encontrado!")
        break
else:
    print("Elemento não encontrado")
Digite um número a pesquisar: 10
Elemento encontrado!
In [71]:
i = 1
while i < 3:
    print(i)
    i += 1
else:
    print("Terminou")
1
2
Terminou
In [72]:
# Programa para achar o máximo de uma lista:
x = [8, 23, 2, 67, 4]
xmax = x[0]
for e in x:
    if e > xmax:
        xmax = e
print(f"Valor máximo de {x} é {xmax}")
Valor máximo de [8, 23, 2, 67, 4] é 67

Exercício 9

Tente converter este programa (exemplo acima)

# Programa para adicionar números a uma lista
L = []
while True:
    n = int(input("Digite um número (0 sai): "))
    if n == 0:
        break
    L.append(n)

usando for.

Explique se for pode ser sempre usado no lugar de while e porquê.

In [ ]:
 

Range

Usamos anteriormente a função range. Esta função cria uma sequência de números e parece ser uma lista mas não é. Sendo uma sequência conhecida, porque gastar memória armazenando todos os elementos?

In [73]:
range(5)
Out[73]:
range(0, 5)
In [74]:
# A função `list` converte para lista:
list(range(5))
Out[74]:
[0, 1, 2, 3, 4]
In [75]:
# Dá para especificar o valor inicial
list(range(3,10))
Out[75]:
[3, 4, 5, 6, 7, 8, 9]
In [76]:
# E também dá para escpeficar o intervalo (passo entre valores:)
list(range(3,33,3))
Out[76]:
[3, 6, 9, 12, 15, 18, 21, 24, 27, 30]
In [77]:
# Mas mais importante, dá para usar nos laços `for`!

for i in range(5):
    print(i)
0
1
2
3
4
In [78]:
for t in range(3,33,3):
    print(t, end=" ") # Repare no `end`
print()
#print("ABCDEF")
3 6 9 12 15 18 21 24 27 30 

enumerate

Muitas vezes (quase sempre?) além do valor do elemento na lista, queremos também o índice. Para isso, usamos enumerate

In [79]:
L = [5,9,13]
i = 0
for e in L:
    print(f"L[{i}] = {e}")
    i += 1
L[0] = 5
L[1] = 9
L[2] = 13
In [80]:
L = [5,9,13]
for i, e in enumerate(L):
    print(f"L[{i}] = {e}")
L[0] = 5
L[1] = 9
L[2] = 13

Exercício 10

Escreva um programa que acha o menor elemento de uma lista

In [ ]:
 

Exercício 11

Modifique o programa para achar o máximo de modo que encontre o máximo mas também encontre o índice onde este máximo ocorre.

In [ ]:
 

Exercício 12

Escreva um programa que encontra o máximo e o mínimo de uma lista

In [ ]:
 

Ordenação de listas

Colocar a lista em ordem crescente ou descrescente é extremamente importante. Aqui vamos apresentar o método de ordenação de bolhas (bubble sort na literatura)

Qual a idéia do algorítmo? Vamos tomar como exemplo a lista

L = [9, 2, 4, 3, 8, 6]

Começamos a percorrer a lista ordenando a lista par a par

  1. [2, 9, 3, 4, 8, 6]
    
  2. [2, 3, 9, 4, 8, 6]
    
  3. [2, 3, 4, 9, 8, 6]
    
  4. [2, 3, 4, 8, 9, 6]
    
  5. [2, 3, 4, 8, 6, 9]
    

    Agora começamos novamente mas não precisamos ir até o final: o maior elemento já está lá!

  6. [2, 3, 4, 8, 6, 9] # Não fez nada 2 < 3
    
  7. [2, 3, 4, 8, 6, 9] # Não fez nada 3 < 4
    
  8. [2, 3, 4, 8, 6, 9] # Não fez nada 4 < 8
    
  9. [2, 3, 4, 6, 8, 9] # Não fez nada 4 < 8
    
    Começamos de novo mas agora só até o penúltimo. Mas agora a lista está ordenada então podemos parar.
In [88]:
L = [9, 2, 4, 3, 8, 6]
N = len(L)
for i in range(N):
    trocou = False
    for k in range(N-i-1):
        if L[k] > L[k+1]: # Inverter a posição
            trocou = True
            tmp = L[k]
            L[k] = L[k+1]
            L[k+1] = tmp
    if not trocou:
        break

L
        
            
            
Out[88]:
[2, 3, 4, 6, 8, 9]

Exercício 13

Modifique o programa anterior para que ordene a lista em modo decrescente

In [95]:
?L.sort

Exercício 14

O que acontece se você tentar usar o programa acima com uma lista de strings? Tente e brinque um pouquinho.

Por outro lado, o que acontece se misturarmos números e strings?

In [ ]:
 

Exercício 15

Um aspecto importante é saber p quão eficiente é este algorítimo. Para tanto, precisamos saber quanto tempo leva para ordenar a lista.

Mas isso vai depender do tamanho da lista, do tipo de dados dentro da lista e do computador que está executando o programa. No entanto, para efeito comparativo, podemos estimar o número de operações. Neste caso, podemos falar em quantas comparações foram realizadas (A linha L[k] > L[k+1]). Também é interessante saber quantas inversões foram realizadas. Estime esse custo para os dois seguintes casos:

  1. Uma lista ordenada de maneira crescente de comprimento N
  2. Uma lista ordenada de maneira decrescente de comprimento N
In [ ]:
 

Métodos das listas

As listas já possuem métodos úteis. Você pode procurar isso na documentação mas também pode ver isso de maneira iterativa no terminal ou no notebook Jupyter. Basta criar uma variável que armazena a lista, digitar esta variável, ponto e pressionar TAB:

x = [2,5,3,8,5,3,5,7,9,]
x.<TAB>
In [110]:
x = [2,5,3,8,5,3,5,7,9,]
In [117]:
x.
Out[117]:
3
In [120]:
?x.
    

Alguns dos métodos:

Se a lista está armazenada em x, temos os seguintes métodos:

  • x.append: adiciona elementos ao final da lista
  • x.clear: apaga todos os elementos da lista
  • x.copy: copia a lista e os elementos
  • x.count: conta o número de ocorrências de um elemento
  • x.extend: extende a lista com os elementos de outra lista
  • x.index: encontra índice de um elemento
  • x.insert: adiciona um elemento na posição antes do índice
  • x.pop: remove e retorna o elemento na posição do índice
  • x.remove: remove a primeira ocorrência de um valor
  • x.reverse: reverte a ordem dos elementos
  • x.sort: reordena os elementos da lista

    Estes métodos são úteis e em geral é recomendado que sejam utilizados: provavelmente são mais rápidos, flexíveis e seguros do que qualquer coisa que você faça.

Exercício 16

Explore os métodos das listas

In [ ]:
 

Exercício 17

Não são apenas as listas que têm métodos. Números e strings também têm métodos. Explore-os da mesma maneira que você fez com os métodos das listas.

In [ ]:
 

Antecipando o futuro: funções

O algorítimo de ordenação pode ser encapsulado numa função. Assim o programa pode ser reutilizado quando for necessário.

In [100]:
def bubble_sort(L):
    N = len(L)
    for i in range(N):
        trocou = False
        for k in range(N-i-1):
            if L[k] > L[k+1]: # Inverter a posição
                trocou = True
                tmp = L[k]
                L[k] = L[k+1]
                L[k+1] = tmp
        if not trocou:
            break
    
In [101]:
L = [23,4,5,2,3,6,2345,6,32,345,4]
In [102]:
bubble_sort(L)
In [103]:
L
Out[103]:
[2, 3, 4, 4, 5, 6, 6, 23, 32, 345, 2345]

Comentários

Comments powered by Disqus