Aula 3 - Trabalhando com Listas

Conceito de Listas

In [1]:
#Para entender listas, primeiro vamos analisar uma string
#como já vimos, uma string permite acessar valores individuais pela posição
#no caso, estamos pegando a letra "u" da posição dois da string
nome='Paulo'
print(nome[2])
u
In [2]:
#Entratanto, a string não permite alterar os valores da posição
#strings são imutáveis
#String é uma cadeia de caracteres, não aceita outros valores
#tentanto alterar a posição, gera erro.
nome[4]='a'
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[2], line 5
      1 #Entratanto, a string não permite alterar os valores da posição
      2 #strings são imutáveis
      3 #String é uma cadeia de caracteres, não aceita outros valores
      4 #tentanto alterar a posição, gera erro.
----> 5 nome[4]='a'

TypeError: 'str' object does not support item assignment
In [ ]:
#Já as listas são estruturas bem mais flexíveis
#As listas aceitam elementos de qualquer tipo em suas posições, inclusive outras listas
#Desta forma, podemos ter uma única lista, com elementos string, float, int e até mesmo outra lista
#O comando abaixo cria uma lista vazia
lista=[]

#        0    1      2              3    4
#       -5   -4     -3             -2   -1
lista = [123, True, 'Luiz Otávio',  1.2, []]
lista[-3] = 'Maria'
print(lista)
print(lista[2], type(lista[2]))
In [3]:
#Mas podemos criar uma lista já com elementos
#No exemplo abaixo criamos um lista com inteiro, string, float e lista (com elementos inteiros)
lista = [455, True, 'Paulo',  2.5, [1,2,3]]
lista
Out[3]:
[455, True, 'Paulo', 2.5, [1, 2, 3]]
In [4]:
#Para acessar elementos da lista, podemos utilizar os índices
#         0     1      2       3      4
#        -5    -4      -3     -2     -1
lista = [455, True, 'Paulo',  2.5, [1,2,3]]
lista[2]
Out[4]:
'Paulo'
In [5]:
#também podemos usar os índices negativos
lista[-3]
Out[5]:
'Paulo'
In [7]:
#Como o elemento da posição 3 é uma string, podemos usar os métodos de string
lista[-3].upper()
Out[7]:
'PAULO'
In [21]:
#para alterar um elemento da lista, basta inserir outro elemento na posição
#no exemplo abaixo, trocamos o 9 (posição 2) por 3
lista=[1,2,9,4,5]
lista[2]=3
lista
Out[21]:
[1, 2, 3, 4, 5]
In [22]:
#Para apagar um elemento, usamos o método "del".
#Entretanto, deve-se evitar usar o del em listas muito grandes porque é uma operação pesada
#O python terá que deslocar todos os índices posteriores ao elemento deslocado
#A lista é ideal para inserção e deleção de elementos no seu final
# abaixo estamos apagando o elemento da posição 2
del lista[2]
lista
Out[22]:
[1, 2, 4, 5]
In [23]:
#observe que agora foi deslocado para posição 2 o elemento da posição 3 (valor 4)
#esse processo de deslocamento é pesado em grandes listas.
lista
Out[23]:
[1, 2, 4, 5]
In [24]:
#o método append adiciona um elemento ao final da lista
lista.append(20)
lista
Out[24]:
[1, 2, 4, 5, 20]
In [25]:
#remove o último elemento da lista
lista.pop()
lista
Out[25]:
[1, 2, 4, 5]
In [26]:
#se colocar uma posição no parâmetro, ele remove,
elemento = lista.pop(1)
elemento
Out[26]:
2
In [27]:
#O método clear limpa a lista (remove todos os elementos)
lista=[1,2,3,4,5]
lista.clear()
lista
Out[27]:
[]
In [28]:
#O comando insert faz a inserção de um elemento na lista.
#Ele possui dois parâmetros, sendo o primeiro a posição e o segundo o valor
lista=[1,2,3,4,5]
lista.insert(2,33)
lista
Out[28]:
[1, 2, 33, 3, 4, 5]
In [1]:
#Concatenar listas consiste em juntar elementos de listas distintas
#esse processo pode ser feito com o sinal de +
lista1 = [11, 2, 5]
lista2 = [4, 5, 6]
lista3 = lista1 + lista2
lista3
Out[1]:
[11, 2, 5, 4, 5, 6]
In [31]:
#o método extendo também concatena valores de listas distintas
lista1 = [1, 2, 3]
lista2 = [4, 5, 6]
lista1.extend(lista2)
lista1
Out[31]:
[1, 2, 3, 4, 5, 6]
In [33]:
#No exemplo a lista2 esta apontando para lista1
#Neste caso, modificando o valor da lista1, aumenticamente muda o valor da lista2
#elas apontam para o mesmo endereço de memória
lista1 = ['Paulo', 'Tereza', 'André']
lista2 = lista1
print(lista2)
#lista1 vai receber um novo valor.
lista1.insert(2,'Zé')
print(lista1)
print(lista2)
['Paulo', 'Tereza', 'André']
['Paulo', 'Tereza', 'Zé', 'André']
['Paulo', 'Tereza', 'Zé', 'André']
In [36]:
#Para fazer uma copia dos valores da lista1 deve-se usar o método copy
#Neste caso é copiado o valor, e não apontado para o mesmo endereço de memória
lista1 = ['Paulo', 'Tereza', 'André']
lista2 = lista1.copy()
print(lista2)
#lista1 vai receber um novo valor.
lista1.insert(2,'Zé')
print(lista1)
#Observe que nada mudou na lista2
print(lista2)
['Paulo', 'Tereza', 'André']
['Paulo', 'Tereza', 'Zé', 'André']
['Paulo', 'Tereza', 'André']
In [38]:
#é possível percorrer os elementos da lista utilizando for 
lista = ['Zé', 'Paulo', 'João']

for elemento in lista:
    print(elemento)
Zé
Paulo
João
In [40]:
#Exemplo 1 - Condirando a lista (lista = ['Maria', 'Helena', 'Luiz']), faça impriir na tela os elementos da lista
#e os seus índices 
lista = ['Tereza', 'Paulo', 'Zé']
indices=range(len(lista))
for indice in indices:
    print(indice, lista[indice])
0 Maria
1 Helena
2 Luiz

Empacotamento

In [44]:
#empacotamento consistem em pegar um elemento de uma lista, e empacotar o restante em outra lista
#como exemplo, o Python permite que variáveis recebam valores de uma lista com a sintaxe abaixo
nome1, nome2, nome3=['Tereza', 'Paulo', 'Zé']
nome2
Out[44]:
'Paulo'
In [46]:
#mas caso só seja necessário o primeiro valor. Neste caso gera um erro
nome1, =['Tereza', 'Paulo', 'Zé']
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[46], line 2
      1 #mas caso só seja necessário o primeiro valor. Neste caso gera um erro
----> 2 nome1, =['Tereza', 'Paulo', 'Zé']

ValueError: too many values to unpack (expected 1)
In [48]:
#mas podemos empacotar o restante dos valores usando o *
#Neste caso, pegaremos o primeiro valor, e o restante será empacotado na variavel resto
nome1, *resto =['Tereza', 'Paulo', 'Zé']
print(nome1)
print(resto)
Tereza
['Paulo', 'Zé']
In [50]:
#Caso não fosse mais necessário os valores restantes, é padrão no Python usar "_" ao invés de resto
#um programador Python quando ver "_", já entenderá que não será usado os dados restantes
nome1, *_ =['Tereza', 'Paulo', 'Zé']
print(nome1)
Tereza
In [52]:
#caso seja necessário pegar o segundo elemento
_,nome2, *_ =['Tereza', 'Paulo', 'Zé']
nome2
Out[52]:
'Paulo'

Fazendo Slice em Lista (pegar elementos)

In [59]:
#Fazer slice consiste em pegar elementos específicos de uma lista
lista=[1,2,3,['a','b','c'],5,[1,2,3],7,8,9]
In [60]:
#retorna o segundo elemento
lista[1]
Out[60]:
2
In [61]:
#retorna os 5 primeiros elementos
lista[0:5]
Out[61]:
[1, 2, 3, ['a', 'b', 'c'], 5]
In [62]:
#retorna 0s elementos entre a segunda e quinta posição
lista[1:5]
Out[62]:
[2, 3, ['a', 'b', 'c'], 5]
In [64]:
#retorna todos os elementos
lista[::]
Out[64]:
[1, 2, 3, ['a', 'b', 'c'], 5, [1, 2, 3], 7, 8, 9]
In [65]:
#retorna, a partir da primeira posição, um elemento sim e o outro não
lista[::2]
Out[65]:
[1, 3, 5, 7, 9]
In [66]:
#retornar o último elemento
lista[-1]
Out[66]:
9
In [70]:
#retornar os 4 últimos elementos
lista[-1:-5:-1]
Out[70]:
[9, 8, 7, [1, 2, 3]]
In [71]:
#pegar o segundo elemento da lista que está na posição 3 da lista principal
lista[3][1]
Out[71]:
'b'
In [3]:
#Fazendo soma de 10 com o segundo elemento da sexta posição da lista principal lista(2+10)
lista=[1,2,3,['a','b','c'],5,[1,2,3],7,8,9]
valor=lista[5][1]+10
valor
Out[3]:
12
In [77]:
#Lista quantos elementos 2 tem na lista
lista.count(2)
Out[77]:
1
In [82]:
#Pegando o index buscando pelo valor
lista.index(5)
Out[82]:
4
In [10]:
#Sorteando elemento da lista com função choice da biblioteca random
import random
cidades=['Curitiba', 'São Paulo', 'Rio de Janeiro']
sorteada=random.choice(cidades)
print("A cidade sorteada é: ",sorteada)
A cidade sorteada é:  São Paulo

Tuplas

In [88]:
#A tupla é uma estrutura muito parecida com a lista, a única diferença é que não permite alteração nos elementos.
#A tupla são listas imutáveis
#Todo o restante é igual as listas
#Como forma de demonstrar a diferença vamos criar uma lista e alterar o segundo elemento
lista=[1,2,3]
lista[1]=32
lista
Out[88]:
[1, 32, 3]
In [89]:
#As tuplas são criadas com parenteses
#Criando uma tupla e tentando alterar o elemento. Gera erro.
tupla=(1,2,3)
tupla[1]=32
tupla
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[89], line 4
      1 #As tuplas são criadas com parenteses
      2 #Criando uma tupla e tentando alterar o elemento. Gera erro.
      3 tupla=(1,2,3)
----> 4 tupla[1]=32
      5 tupla

TypeError: 'tuple' object does not support item assignment
In [90]:
#Apagando elemento da lista
del lista[1]
lista
Out[90]:
[1, 3]
In [91]:
#Tentando apagar elemento da tupla
del tupla(1)
tupla
  Cell In[91], line 2
    del tupla(1)
        ^
SyntaxError: cannot delete function call
In [93]:
#É possível fazer a conversão de uma lista em tupla (tuplar)
#Isso pode ser vantajoso, pois as tuplas são estruturas mais rápidas do que as listas
lista=[1,2,3]
tupla=tuple(lista)
print(tupla, type(tupla))
(1, 2, 3) <class 'tuple'>
In [3]:
#A função sum faz a soma dos elementos de uma lista
lista = [4, 7, 2, 9, 5]
soma = sum(lista)
print(soma)
27
In [2]:
#O método sort ordena uma lista
lista = [4, 7, 2, 9, 5]
lista.sort()
print(lista)
[2, 4, 5, 7, 9]
In [8]:
#Funções max e min retornam os maiores e menores números de uma lista
lista = [4, 7, 2, 9, 5]
print(max(lista))
print(min(lista))
9
2
In [10]:
#Metodo reverse inverte os elementos da lista
lista = [4, 7, 2, 9, 5]
lista.reverse()
print(lista)
[5, 9, 2, 7, 4]
In [1]:
#Enumerate serve para colocar números (índices) nos valores de uma lista
#ele enumera cada valor da lista
#criando uma lista
lista=["Paulo","Tereza","Chuck"]
lista_numerada=enumerate(lista)
In [2]:
#se tentar imprimir pararece um iterator. Precisa utiliza o for
print(lista_numerada)
<enumerate object at 0x71c6aaeec900>
In [3]:
#Utilizando o for é possível impŕimir os valores
#observe que cada valor possui um número correspondente
for item in lista_numerada:
    print(item)
(0, 'Paulo')
(1, 'Tereza')
(2, 'Chuck')
In [11]:
#também é possível converter o iterator para lista
lista_numerada=list(enumerate(lista))
lista_numerada
Out[11]:
[(0, 'Paulo'), (1, 'Tereza'), (2, 'Chuck')]
In [5]:
#é possível separar os valores enumerados e os valores da lista numerada
for item in enumerate(lista):
    indice, nome = item
    print(indice, nome)
0 Paulo
1 Tereza
2 Chuck
In [12]:
#o python permite colocar as duas variáveis já diretamente no for para facilitar
#observe que o efeito no FOR é o mesmo do exemplo anterior
#também é possível localizar o valor da lista pelo índice
for indice, nome in enumerate(lista):
    print(indice, nome, lista[indice])
0 Paulo Paulo
1 Tereza Tereza
2 Chuck Chuck

Faça uma lista de compras. Basicamente, você terá que criar uma lista, e permitir que o usuário escolha as opções de inserir, listar e apagar os valores. Quando for apagar, deve-se perguntar o índice que deseja apagar. Não permita que o programa gere erros quando o usuário entrar com índices inexistentes na lista.

In [ ]:
#usaremos para os.system('clear') limpar a tela
import os
#criamos a lista vazia
lista = []

while True:
    print('Selecione uma opção')
    opcao = input('[i]nserir [a]pagar [l]istar: ')

    #inserir valores
    if opcao == 'i':
        #limpa a tela
        os.system('clear')
        #recebe o valor que o usuário digitou
        valor = input('Valor: ')
        #adiciona na lista
        lista.append(valor)

    #opção de apagar
    elif opcao == 'a':
        indice_str = input('Escolha o índice para apagar: ')
        #usa o try porque o valor do índice pode não existir
        try:
            #converte para inteiro
            indice = int(indice_str)
            #apaga da lista com base no indice
            del lista[indice]
        #caso gere erro na conversa para inteiro    
        except ValueError:
            print('Digite um número inteiro.')
        #caso gere erro por índice inexistente
        except IndexError:
            print('Índice não existe na lista')
        #caso gere outro erro não identificado (geral)
        except Exception:
            print('Erro desconhecido')
    #opção para listar os valores
    elif opcao == 'l':
        os.system('clear')
        #verifica se a lista está vazia
        if len(lista) == 0:
            print('Nada para listar')
        #colocamos um enumerador na lista e imprimimos
        for i, valor in enumerate(lista):
            print(i, valor)
    #caso o usuário não entre com as 3 opções possíveis
    else:
        print('Por favor, escolha i, a ou l.')
Selecione uma opção

Imprecisão de Valores Decimais

O Python (como a maioria das linguagens de programação) usa o padrão IEEE 754 para representar números de ponto flutuante em binário. O problema é que alguns números decimais não têm representação exata em binário, assim como a fração 1/3 não pode ser representada com precisão em decimal (0.333...).

Exemplo: O número 0.1 em binário vira uma fração infinita: 0.00011001100110011... (repetindo infinitamente)

Como o computador precisa cortar essa representação em algum ponto, ele armazena uma aproximação, e isso gera pequenos erros de precisão.

In [3]:
num1=0.1
num2=0.7
soma=num1+num2
print(soma)
0.7999999999999999
In [4]:
#Primeira forma de contornar isso é fazer a formatação com f'string
num1=0.1
num2=0.7
soma=num1+num2
print(f'{soma:.2f}')
0.80
In [5]:
#A segunda forma é usar round
num1=0.1
num2=0.7
soma=num1+num2
print(round(soma,2))
0.8
In [7]:
#A terceira forma é usar o pacote decimal, com a classe Decimal.
#Só é necessário para números decimais grandes onde é necessário precisão extrema
import decimal
 
num1 = decimal.Decimal('0.1')
num2 = decimal.Decimal('0.7')
soma = num1+num2
print(soma)
0.8
In [12]:
#Agora fazer entender como fazer fatiamento de strings com split
#O split separa uma string com base em uma separador
#No exemplo, será gerada uma lista com as duas partes da string que foram separadas com base na vírgula
frase='O Python é bom para IA, mas também para Automação'
lista=frase.split(', ')
print(lista[0])
print(lista[1])
O Python é bom para IA
mas também para Automação
In [16]:
#O método join faz o processo contrário, une as strings.
#no caso, vamos juntar as strings inserindo uma vírgula novamente
texto=', '.join(lista)
print(texto)
O Python é bom para IA, mas também para Automação
In [21]:
#Operador ternário serve para comparar de forma simplificada
condicao=9
variavel = 'Valor' if condicao==10 else 'Outro valor'
print(variavel)
Outro valor
In [24]:
#é possível ter diversas comparações
condicao=9
variavel = '10' if condicao==10 else '8' if condicao==8 else '9'
print(variavel)
9
In [ ]: