list
(estrutura sequencial indexada) len()
e método append()
for i in range(início,fim,passo):
for item in lista:
+
*
Antes de sua aula síncrona desta semana, estude os conteúdos abaixo e os materiais recomendados e tente resolver os exercícios. Os assuntos e exercícios serão discutidos pelo(a) professor(a) na aula.
Até aqui, trabalhamos com variáveis simples, capazes de armazenar apenas um tipo, como bool
, float
e int
.
Uma lista (tipo list
) em Python é uma sequência de valores de qualquer tipo ou classe tais como int
, float
, bool
, str
e mesmo list
, entre outros.
Existem várias maneiras de criarmos uma lista. A maneira mais simples é envolver os elementos da lista por colchetes ([
e ]
). Por exemplo, podemos criar uma lista contendo os anos de obtenção das 5 primeiras conquistas do Brasil em Copas do Mundo de Futebol da seguinte maneira:
>>> anos_conquistas = [1958, 1962, 1970, 1994, 2002]
Observe o uso de colchetes de abertura ([
) para marcar o início e o
colchetes de fechamento (]
) para marcar o final da lista, e os elementos separados
por vígula.
Ao contrário do conceito de vetores em linguagem C, que são coleções indexadas homogêneas de dados (todos elementos do vetor são de um mesmo tipo), as listas em Python podem conter vários tipos de dados, sendo, portanto, possível armazenar coleções heterogêneas de dados.
>>> L = [1958, 1962, 1970, 1994, 2002]
Lista são estruturas sequenciais indexadas pois seus elementos podem ser acessados sequencialmente utilizando índices. Por convenção do Python, o primeiro elemento da lista tem índice 0, o segundo tem índice 1, e assim por diante. Observe que, por começar pelo índice zero, o último elemento da lista anos_conquistas
, o ano 2002, tem índice 4, sendo que essa lista tem comprimento 5.
Índices negativos indicarão elementos da direita para a esquerda ao invés de da esquerda para a direita.
Um erro comum em programas é a utilização de índices inválidos.
len()
.
>>> len(anos_conquistas)
5
n > 0
e uma sequência com n
números reais, imprimí-los na ordem inversa a da leitura.
Dica: Criar uma lista vazia (seq = []
) e usar append
.
Solução 1:
Vamos fazer do modo tradicional, imprimindo dentro de um while
.
n = int(input("Digite n: ")) seq = [] i = 0 # Lê a sequência de números, armazenando-os em uma lista while i < n: num = float(input("Digite o %do. num: "%(i+1))) seq.append(num) i += 1 # Percorre os elementos da lista do último ao primeiro, # imprimindo-os um por vez i = n-1 while i >= 0: print(seq[i]) i -= 1
Solução 2:
Solução alternativa usando índices negativos.
n = int(input("Digite n: ")) seq = [] i = 0 while i < n: num = float(input("Digite o %do. num: "%(i+1))) seq.append(num) i += 1 i = -1 while i >= -n: print(seq[i]) i -= 1
Solução 3:
Solução alternativa usando o comando for
.
n = int(input("Digite n: ")) seq = [] for i in range(n): num = float(input("Digite o %do. num: "%(i+1))) seq.append(num) for i in range(n-1, -1, -1): print(seq[i])
Solução 4:
Outra solução alternativa usando o comando for
com índices negativos.
n = int(input("Digite n: ")) seq = [] for i in range(n): num = float(input("Digite o %do. num: "%(i+1))) seq.append(num) for i in range(-1, -n-1, -1): print(seq[i])
Solução 5:
O tipo list
possui o método reverse()
, que inverte os elementos da lista.
Usando esse método, a solução do exemplo poderia ser escrita como mostrado a seguir:
n = int(input("Digite n: ")) seq = [] for i in range(n): num = float(input("Digite o %do. num: "%(i+1))) seq.append(num) seq.reverse() for x in seq: print(x)
Solução:
def menorMaiorLista(lista): maior = lista[0] menor = lista[0] for x in lista: if x > maior: maior = x elif x < menor: menor = x return menor,maiorEssa função poderia ser testada no IDLE, por exemplo, com a seguinte chamada:
m,M = menorMaiorLista([5,-4,18,8,-9,4]) print("menor =",m,", maior=",M)
A
a uma segunda variável B
não cria uma nova lista.
As duas variáveis estarão referenciando a mesma lista
na memória. Isto significa que alterações na
lista A afetam B e vice-versa:
>>> A = ["Bento Gonçalves", "Campos do Jordão", "Gramado"]
>>> B = A
>>> B.append("Ouro Preto")
>>> print(B)
['Bento Gonçalves', 'Campos do Jordão', 'Gramado', 'Ouro Preto']
>>> print(A)
['Bento Gonçalves', 'Campos do Jordão', 'Gramado', 'Ouro Preto']
>>> id(A)
139789181142280
>>> id(B)
139789181142280
>>> id(A) == id(B)
True
>>> A is B
True
Cada objeto em Python, incluindo listas, possui um identificador exclusivo (número inteiro único) que pode ser acessado usando a função
id()
do Python.
Observe que no exemplo acima, as listas A e B possuem o mesmo identificador,
confirmando que elas correspondem à mesma lista na memória.
O teste id(A) == id(B)
pode ser igualmente obtido através do comando
A is B
.
Em algumas situações, no entanto,
precisamos, de fato, criar uma réplica/clone na
memória de uma lista existente.
Para isso podemos usar o comando B = list(A)
.
Note que nesse caso alterações posteriores em uma das listas não
afetam a sua cópia.
>>> A = ["Bento Gonçalves", "Campos do Jordão", "Gramado"]
>>> B = list(A)
>>> B.append("Ouro Preto")
>>> print(B)
['Bento Gonçalves', 'Campos do Jordão', 'Gramado', 'Ouro Preto']
>>> print(A)
['Bento Gonçalves', 'Campos do Jordão', 'Gramado']
>>> id(A)
139789180697672
>>> id(B)
139789156561992
>>> id(A) == id(B)
False
>>> A is B
False
def insereSeNovo(x, lista):
que devolve o índice em que o real x
ocorre em lista
ou, caso x
não estiver
na lista, insere x
no final da lista e
devolve o índice dessa posição.
n
e uma sequência de n
números reais, escreva um programa (usando a função do item anterior)
que conta e imprime quantas vezes cada número ocorre na sequência.Solução 1:
def insereSeNovo(x, lista): i = 0 achou = False while i < len(lista) and not achou: if lista[i] == x: achou = True ind = i i += 1 if not achou: lista.append(x) ind = len(lista)-1 return ind # programa principal: def main(): n = int(input("Digite n: ")) i = 0 listaNum = [] listaCont = [] while i < n: num = float(input("Digite num: ")) ind = insereSeNovo(num, listaNum) if ind >= len(listaCont): listaCont.append(0) listaCont[ind] += 1 i += 1 i = 0 while i < len(listaNum): print("%.2f aparece %d vezes"%(listaNum[i],listaCont[i])) i += 1 main()
Solução 2:
Uma solução mais compacta para a função
insereSeNovo
:
def insereSeNovo(x, lista): i = 0 while i < len(lista): if lista[i] == x: return i i += 1 lista.append(x) return len(lista)-1
Solução 3:
Uma solução alternativa para a função
insereSeNovo
que utiliza o comando if x not in lista:
def insereSeNovo(x, lista): if x not in lista: lista.append(x) ind = len(lista)-1 else: # eu sei que x está na lista ind = 0 while lista[ind] != x: ind += 1 return ind
+
+
. Note que as listas originais são preservadas e uma nova
lista é criada com um total de elementos igual a soma dos comprimentos das duas primeiras. Veja os exemplos abaixo digitados no Python Shell:
>>> A = ["Bento Gonçalves", "Campos do Jordão", "Gramado"]
>>> B = ["Ouro Preto", "Fortaleza", "Maceió", "Rio de Janeiro"]
>>> C = A + B
>>> print(A)
['Bento Gonçalves', 'Campos do Jordão', 'Gramado']
>>> print(B)
['Ouro Preto', 'Fortaleza', 'Maceió', 'Rio de Janeiro']
>>> print(C)
['Bento Gonçalves', 'Campos do Jordão', 'Gramado', 'Ouro Preto', 'Fortaleza', 'Maceió', 'Rio de Janeiro']
>>> len(C) == len(A) + len(B) #7 == 3 + 4
True
Note que a concatenação não possui propriedade comutativa, pois a ordem dos elementos na lista de saída depende da ordem dos operandos.
>>> sabores = ["baunilha", "chocolate", "morango"] + ["napolitano", "flocos"]
>>> print(sabores)
['baunilha', 'chocolate', 'morango', 'napolitano', 'flocos']
>>> sabores = ["napolitano", "flocos"] + ["baunilha", "chocolate", "morango"]
>>> print(sabores)
['napolitano', 'flocos', 'baunilha', 'chocolate', 'morango']
Se as duas listas A e B possuem elementos em comum, após a concatenação, estes serão repetidos na lista produzida (veja o caso dos elementos 3, 5 e 7 no exemplo abaixo).
>>> impares = [1, 3, 5, 7, 9] #cinco primeiros números ímpares
>>> primos = [2, 3, 5, 7, 11] #cinco primeiros números primos
>>> uniao = impares + primos
>>> print(uniao)
[1, 3, 5, 7, 9, 2, 3, 5, 7, 11]
>>> sabores = ["baunilha", "chocolate", "morango"]
>>> sabores = sabores + ["flocos"]
>>> print(sabores)
['baunilha', 'chocolate', 'morango', 'flocos']
>>> sabores = ["baunilha", "chocolate", "morango"]
>>> sabores += ["flocos"]
>>> print(sabores)
['baunilha', 'chocolate', 'morango', 'flocos']
>>> sabores = ["baunilha", "chocolate", "morango"]
>>> sabores.append("flocos")
>>> print(sabores)
['baunilha', 'chocolate', 'morango', 'flocos']
Apesar deles produzirem o mesmo resultado, nesse caso é
preferível utilizar o método
append()
, pois
a concatenação gera uma cópia da lista toda
e a variável sabores
passa a referenciar essa nova lista criada,
sendo, portanto, uma operação mais custosa.
*
>>> [0, 1]*3 #O mesmo que: [0, 1] + [0, 1] + [0, 1]
[0, 1, 0, 1, 0, 1]
Veja o vídeo abaixo sobre manipulação de listas em Python:
lista[início:fim]
Caso omitido, o parâmetro início
é assumido como sendo 0 (zero) e o fim
, quando omitido,
é assumido como sendo len(lista)
.
Veja os exemplos abaixo digitados no Python Shell:
>>> cidades = ['Bento Gonçalves', 'Campos do Jordão', 'Gramado', 'Ouro Preto', 'Fortaleza', 'Maceió', 'Rio de Janeiro']
>>> cidades[2:6]
['Gramado', 'Ouro Preto', 'Fortaleza', 'Maceió']
>>> cidades[1:3]
['Campos do Jordão', 'Gramado']
>>> cidades[:4]
['Bento Gonçalves', 'Campos do Jordão', 'Gramado', 'Ouro Preto']
>>> cidades[3:]
['Ouro Preto', 'Fortaleza', 'Maceió', 'Rio de Janeiro']
Por convenção do Python, o início
indica o índice do primeiro elemento que será incluído no trecho copiado,
mas o último elemento incluído no trecho é dado por
fim-1
.
Ou seja, o elemento cujo índice é dado por fim
nunca é incluído no trecho copiado.
Em especial, o comando lista[:]
(ou
lista[0:len(lista)]
)
gera uma cópia da lista toda, podendo ser usado em operações
de clonagem de uma lista, no lugar do comando
list(lista)
visto anteriormente:
>>> cidades = ["Bento Gonçalves", "Campos do Jordão", "Gramado"]
>>> B = cidades[:]
>>> id(cidades) == id(B)
False
>>> B.append("Ouro Preto")
>>> print(B)
['Bento Gonçalves', 'Campos do Jordão', 'Gramado', 'Ouro Preto']
>>> print(cidades)
['Bento Gonçalves', 'Campos do Jordão', 'Gramado']
del
ou o método pop
.del
é
del lista[índice]
.
>>> cidades = ["Bento Gonçalves", "Campos do Jordão", "Gramado", "Ouro Preto"]
>>> i = 1 #índice a ser removido
>>> del cidades[i]
>>> print(cidades)
['Bento Gonçalves', 'Gramado', 'Ouro Preto']
A sintaxe do pop
é
lista.pop(índice)
.
A diferença é que o pop
devolve o valor removido da lista, que pode, por exemplo, ser atribuído a uma variável.
Caso omitido o índice, o último elemento é removido.
>>> cidades = ["Bento Gonçalves", "Campos do Jordão", "Gramado", "Ouro Preto"]
>>> i = 1 #índice a ser removido
>>> c = cidades.pop(i)
>>> print(cidades)
['Bento Gonçalves', 'Gramado', 'Ouro Preto']
>>> print(c)
Campos do Jordão
>>> c = cidades.pop()
>>> print(cidades)
['Bento Gonçalves', 'Gramado']
>>> print(c)
Ouro Preto
O efeito da remoção pode também ser obtido construindo uma nova lista sem o elemento indesejado, usando fatiamento mais concatenação.
>>> cidades = ["Bento Gonçalves", "Campos do Jordão", "Gramado", "Ouro Preto"]
>>> i = 1 #índice a ser removido
>>> cidades = cidades[:i] + cidades[i+1:]
>>> print(cidades)
['Bento Gonçalves', 'Gramado', 'Ouro Preto']
Note, porém, que essa última solução é mais custosa,
por envolver a criação de uma cópia da lista toda,
sendo que a variável cidades
passará a referenciar a nova lista gerada.
Assista o vídeo abaixo, que fala sobre como os objetos são armazenados na memória e o que são as variáveis em relação a isso.
n > 0
lançamentos de uma roleta
(números entre 0 e 36), calcular a frequência de cada número.
Dica: Criar uma lista com 37 zeros.
Solução 1:
Solução usando o comando while
.
n = int(input("Digite n: ")) freq = [] i = 0 while i < 37: freq.append(0) i += 1 i = 0 while i < n: num = int(input("roleta: ")) freq[num] += 1 i += 1 i = 0 while i < 37: print("freq.rel.(%d): %f"%(i,freq[i]/n)) i += 1
Solução 2:
Solução mais compacta usando freq = [0]*37
para a criação da lista com 37 zeros.
n = int(input("Digite n: ")) freq = [0]*37 i = 0 while i < n: num = int(input("roleta: ")) freq[num] += 1 i += 1 i = 0 while i < 37: print("freq.rel.(%d): %f"%(i,freq[i]/n)) i += 1
Solução 3:
Solução alternativa usando o comando for
.
n = int(input("Digite n: ")) freq = [0]*37 for i in range(n): num = int(input("roleta: ")) freq[num] += 1 i = 0 for x in freq: print("freq.rel.(%d): %f"%(i,x/n)) i += 1
Solução 4:
Solução alternativa que simula a roleta usando
o gerador de números pseudo-aleatórios do
módulo random
do Python,
ao invés de solicitar a entrada manual dos n
lançamentos.
import random n = int(input("Digite n: ")) freq = [0]*37 for i in range(n): num = random.randrange(0, 37) freq[num] += 1 i = 0 for x in freq: print("freq.rel.(%d): %f"%(i,x/n)) i += 1
n > 0
números reais,
imprimi-los eliminando as repetições.
Solução 1:
Solução usando while
.
n = int(input("Digite n: ")) seq = [] for i in range(n): num = float(input("Digite o %do. num: "%(i+1))) rep = False j = 0 while j < len(seq) and rep == False: if seq[j] == num: rep = True j += 1 if rep == False: # if not rep: seq.append(num) print(seq)
Solução 2:
Solução usando for
.
n = int(input("Digite n: ")) seq = [] for i in range(n): num = float(input("Digite o %do. num: "%(i+1))) rep = False for x in seq: if x == num: rep = True if rep == False: # if not rep: seq.append(num) print(seq)
Solução 3:
Solução compacta, aproveitando o fato de
que o Python permite testar diretamente se um elemento não faz parte de uma
lista,
através do comando if num not in seq:
n = int(input("Digite n: ")) seq = [] for i in range(n): num = float(input("Digite o %do. num: "%(i+1))) if num not in seq: seq.append(num) print(seq)
n
e m
e duas sequências ordenadas com n > 0
e m > 0
números inteiros, criar uma lista
contendo a sequência ordenada com todos os elementos das
duas sequências originais sem repetição.Sugestão: Imagine uma situação real, por exemplo, dois fichários de uma biblioteca.
Solução 1:
Cada sequência ordenada fornecida é lida em uma
lista correspondente já eliminando possíveis elementos repetidos,
usando a solução empregada no problema anterior.
As duas listas resultantes seq1
e seq2
são então percorridas, usando as variáveis i
e j
como seus respectivos índices, copiando de modo intercalado para uma lista de saída seq3
sempre o menor valor entre seq1[i]
e seq2[j]
.
n = int(input("Digite n: ")) seq1 = [] for i in range(n): num = int(input("Digite o %do. num: "%(i+1))) if num not in seq1: seq1.append(num) m = int(input("Digite m: ")) seq2 = [] for i in range(m): num = int(input("Digite o %do. num: "%(i+1))) if num not in seq2: seq2.append(num) seq3 = [] i,j = 0,0 while i < len(seq1) and j < len(seq2): if seq1[i] < seq2[j]: seq3.append(seq1[i]) i += 1 elif seq2[j] < seq1[i]: seq3.append(seq2[j]) j += 1 else: # seq1[i] == seq2[j] seq3.append(seq1[i]) i += 1 j += 1 while i < len(seq1): seq3.append(seq1[i]) i += 1 while j < len(seq2): seq3.append(seq2[j]) j += 1 print(seq3)
Solução 2:
Solução similar à anterior,
porém durante o processo de intercalação,
os casos em que i
ou j
excedem
o último índice válido de suas respectivas listas
é tratado diretamente dentro do mesmo laço que
trata os demais casos em que os dois índices são válidos.
n = int(input("Digite n: ")) seq1 = [] for i in range(n): num = int(input("Digite o %do. num: "%(i+1))) if num not in seq1: seq1.append(num) m = int(input("Digite m: ")) seq2 = [] for i in range(m): num = int(input("Digite o %do. num: "%(i+1))) if num not in seq2: seq2.append(num) seq3 = [] i,j = 0,0 while i < len(seq1) or j < len(seq2): if i == len(seq1): seq3.append(seq2[j]) j += 1 elif j == len(seq2): seq3.append(seq1[i]) i += 1 elif seq1[i] < seq2[j]: seq3.append(seq1[i]) i += 1 elif seq2[j] < seq1[i]: seq3.append(seq2[j]) j += 1 else: # seq1[i] == seq2[j] seq3.append(seq1[i]) i += 1 j += 1 print(seq3)
Solução 3:
Idêntica à solução anterior, exceto que exploramos o fato de que as duas sequências fornecidas estão ordenadas, de modo que para eliminar seus elementos repetidos durante o laço de leitura, basta comparar com o último valor já lido na lista.
n = int(input("Digite n: ")) num = int(input("Digite o 1o. num: ")) seq1 = [num] for i in range(1,n): num = int(input("Digite o %do. num: "%(i+1))) if num != seq1[len(seq1)-1]: #compara com o último valor inserido em seq1. seq1.append(num) m = int(input("Digite m: ")) num = int(input("Digite o 1o. num: ")) seq2 = [num] for i in range(1,m): num = int(input("Digite o %do. num: "%(i+1))) if num != seq2[len(seq2)-1]: #compara com o último valor inserido em seq2. seq2.append(num) seq3 = [] i,j = 0,0 while i < len(seq1) or j < len(seq2): if i == len(seq1): seq3.append(seq2[j]) j += 1 elif j == len(seq2): seq3.append(seq1[i]) i += 1 elif seq1[i] < seq2[j]: seq3.append(seq1[i]) i += 1 elif seq2[j] < seq1[i]: seq3.append(seq2[j]) j += 1 else: # seq1[i] == seq2[j] seq3.append(seq1[i]) i += 1 j += 1 print(seq3)
l1
e l2
) e devolve True
caso:
l1
e l2
tem o mesmo tamanho el1
e l2
são
todos iguais e na mesma ordem.False
.n > 0
e determina se ele é ou não palíndromo usando as
funções anteriores.
Um número inteiro é palíndromo se ele
possui a mesma sequência de dígitos quando
lido tanto da direita para a esquerda como da esquerda para a direita.
Solução 1:
def listaDeDigitos(n): lista = [] while n > 0: dig = n%10 lista.append(dig) n = n//10 return lista def ordemReversa(lista): inv = [] i = len(lista)-1 while i >= 0: inv.append(lista[i]) i -= 1 return inv def iguais(l1, l2): if len(l1) != len(l2): return False i = 0 while i < len(l1): if l1[i] != l2[i]: return False i += 1 return True # programa principal: def main(): n = int(input("Digite n: ")) lista = listaDeDigitos(n) inv = ordemReversa(lista) if iguais(lista, inv): print(n,"é palíndromo") else: print(n,"não é palíndromo") main()
Soluções alternativas:
Uma implementação alternativa para a
função ordemReversa
.
Nessa versão usamos, no início do código,
o comando [0]*n
que gera uma lista com n
elementos nulos.
def ordemReversa(lista): n = len(lista) inv = [0]*n i = 0 while i < n: inv[i] = lista[n-1-i] i += 1 return invPython permite a comparação de listas (ex:
if l1 == l2:
).iguais
poderia se resumir simplesmente a:
def iguais(l1, l2): return l1 == l2
Observações:
Python permite inverter listas (in place) usando lista.reverse()
.
Para criar uma cópia de uma lista a
podemos usar b = list(a)
, ou usar b = a[:]
Logo, uma solução para o programa principal
usando esses recursos disponíveis na linguagem poderia ser:
def main(): n = int(input("Digite n: ")) lista = listaDeDigitos(n) inv = list(lista) inv.reverse() if inv == lista: print(n,"é palíndromo") else: print(n,"não é palíndromo") main()
ini
e fim
, e uma lista L
,
tal que 0 <= ini < fim <= len(L)
e calcula a
soma dos elementos L[i]
, para ini <= i < fim
.n > 0
e uma sequência com n
números reais, e determina um segmento de soma máxima.
Um segmento é uma subsequência de
números consecutivos, com pelo menos um
elemento.
Exemplo: Na sequência abaixo com n = 12
5, 2, -2, -7, 3, 14, 10, -3, 9, -6, 4, 1,
a soma do segmento de soma máxima é 3+14+10-3+9 = 33.
Solução 1:
def somasegmento(ini,fim,L): soma = 0.0 i = ini while i < fim: soma += L[i] i += 1 return soma def main(): n = int(input("Digite n: ")) lista = [] for i in range(n): num = float(input("Digite num: ")) lista.append(num) smax = lista[0] imax,fmax = 0,1 for i in range(n): for f in range(i+1,n+1): s = somasegmento(i,f,lista) if s > smax: smax = s imax = i fmax = f print("Soma máxima =",lista[imax],end=" ") for i in range(imax+1,fmax): if(lista[i] < 0.0): print(lista[i],end=" ") else: print("+",lista[i],end=" ") print("=",smax) main()
Solução 2:
Solução alternativa da função
somasegmento
usando o laço for
.
def somasegmento(ini,fim,L): soma = 0.0 for i in range(ini, fim): soma += L[i] return soma
Solução 3:
Solução compacta, aproveitando os
recursos já existentes do Python de fatiamento de listas
e soma dos valores de uma lista usando a função sum
(exemplo, sum([3,-2,7])
gera o valor 8).
def somasegmento(ini,fim,L): return sum(L[ini:fim])