Pular para conteúdo

Listas

Listas são um tipo de variável que permite o armazenamento de vários valores, que podem ser acessados por um índice. Listas são mutáveis, o que significa que seu conteúdo pode ser alterado durante a execução do programa, ou seja, itens podem ser adicionados ou removidos. Uma lista pode conter zero ou mais elementos de um mesmo tipo (duplicados ou não) ou de tipos diversos, podendo inclusive conter outras listas. O tamanho de uma lista é igual à quantidade de elementos que ela contém.

Veja como é simples criar uma lista com alguns números inteiros:

N = [2, 4, 8]
print(N) # [2, 4, 8]

Na primeira linha, usamos colchetes ([]) para criar uma lista que contém três elementos e, em seguida, atribuímos à variável N (dizemos que o tamanhos da lista N é 3). Na segunda linha, a lista é impressa através do nome da variável. Todos os elementos são impressos na mesma ordem em que foram armazenados na lista.

Aqui está outra lista que contém três strings:

disciplinas = ["Cálculo 1", "Programação I", "Algebra Linear"]
print(disciplinas) # ["Cálculo 1", "Programação I", "Algebra Linear"]

Como dito, uma lista pode conter elementos de um mesmo tipo ou de tipos diversos. Por exemplo:

1
2
3
4
vogais = ['a', 'e', 'i', 'o', 'u']
nomes = ['Paulo', 'Andre', 'Julio']
notas = [10, 10, 5, 6, 7, 8.5, 9.3, 7.8]
info = ['Paulo', 22, 1.78]

Note que a lista notas contém elementos repetidos e a lista info contém elementos de diferentes tipos.

Os colchetes vazios ([]) e a função de list() podem ser usados ​​para criar listas vazias que não possuem nenhum elemento.

lista_vazia_1 = list()
lista_vazia_2 = []

Tamanho de uma lista

Às vezes, precisamos saber quantos elementos existem em uma lista. Existe uma função integrada chamada len que pode ser aplicada a qualquer sequência e retorna o seu tamanho. Portanto, quando aplicado a uma lista, ela retorna o número de elementos dessa lista.

1
2
3
4
5
6
N = [1, 2, 3, 4, 5]
print(len(N)) # 5
lista_vazia = []
print(len(lista_vazia)) # 0
tam = len(N)
print(tam) # 5

Índices

Uma maneira de acessar os elementos individuais de uma lista (assim como cada caractere em uma string) é através do índice. Cada elemento em uma lista possui um índice que especifica sua posição na lista. O índice começa em 0, portanto, o índice do primeiro elemento é 0, o índice do segundo elemento é 1 e assim por diante. O índice do último elemento em uma lista é 1 menos que o número de elementos na lista.

Para acessar um elemento de uma lista por seu índice, precisamos usar colchetes. Adicionamos os colchetes após a lista e, entre eles, escrevemos o índice de um elemento que desejamos obter. Veja um exemplo:

1
2
3
4
disciplinas = ["Cálculo 1", "Programação I", "Algebra Linear"]
primeiro_elem = disciplinas[0] # "Cálculo 1"
segundo_elem = disciplinas[1]  # "Programação I"
terceiro_elem = disciplinas[2] # "Algebra Linear"

Lembre-se que os índices começam em 0 e, portanto, o índice do último elemento é igual a len(lista) - 1. Assim, tentar acessar uma posição maior que o número de elementos da lista menos 1 gera um erro (IndexError). Por exemplo:

quarto_elem = disciplinas[3] # IndexError: list index out of range

Em Python, também é possível usar índices negativos com listas para identificar as posições dos elementos em relação ao final da lista. O índice -1 identifica o último elemento em uma lista, -2 identifica o penúltimo elemento e assim por diante. Nesse caso, o primeiro elemento de uma lista também pode ser acessado usando -len(lista). O código a seguir mostra um exemplo:

1
2
3
4
5
disciplinas = ["Cálculo 1", "Programação I", "Algebra Linear"]
print(disciplinas[-1]) # Algebra Linear 
print(disciplinas[-2]) # Programação I
print(disciplinas[-3]) # Cálculo 1
print(disciplinas[-4]) # IndexError: list index out of range

A figura abaixo mostra o conceito geral de índices em uma lista:

Índices de uma lista

Como já dito, as listas em Python são mutáveis, o que significa que seus elementos podem ser alterados. Utilizando o nome da lista e um índice, podemos mudar o conteúdo de um elemento. Por exemplo:

1
2
3
4
5
disciplinas = ["Cálculo 1", "Programação I", "Algebra Linear"]
print(disciplinas[0]) # Cálculo 1
disciplinas[0] = "Calculo 2"
print(disciplinas[0]) # Cálculo 2
print(disciplinas) # ["Cálculo 2", "Programação I", "Algebra Linear"]

Incluindo elementos

Uma alternativa para incluir elementos em uma determinada lista é utilizando o método append(). Ele faz com que o elemento seja adicionado no final da lista. A sua sintaxe básica é a seguinte:

<lista>.append(<elemento>)

onde <lista> é o nome da variável do tipo lista e <elemento> é o elemento que deve ser incluído no fim da lista. Veja um exemplo:

1
2
3
4
5
6
disciplinas = [] # Cria uma lista vazia
disciplinas.append("Cálculo 1")
disciplinas.append("Programação I")
disciplinas.append("Algebra Linear")
print(disciplinas) 
# ["Cálculo 1", "Programação I", "Algebra Linear"]

Veja outro exemplo em que é feita a leitura de notas de uma turma enquanto não for digitado um valor negativo.

1
2
3
4
5
6
7
notas = []
while True:
    nota = float(input("Digite uma nota (valor < 0 para finalizar): "))
    if nota < 0: # Finaliza a leitura quando um valor negativo for digitado
        break
    notas.append(nota)
print(notas)

Outra forma de incluir elementos em uma lista é utilizando o método insert(). A diferença desse método para o append() é que você especifica em qual índice deseja incluir o novo elemento. Observe a sintaxe básica:

<lista>.insert(<índice>, <elemento>)

Veja um exemplo:

1
2
3
4
disciplinas = ["Cálculo 1", "Programação I", "Algebra Linear"]
disciplinas.insert(1, "Introdução à Programação")
print(disciplinas) 
# ['Cálculo 1', 'Introdução à Programação', 'Programação I', 'Algebra Linear']

Se o índice do insert() foi maior que o tamanho da lista, o elemento será incluído no fim da mesma.

disciplinas = ["Cálculo 1", "Programação I", "Algebra Linear"]
disciplinas.insert(10, "Introdução à Programação")
print(disciplinas)
# ['Cálculo 1', 'Programação I', 'Algebra Linear', 'Introdução à Programação']

Removendo elementos

Para remover elementos de uma lista, existem os métodos remove() e pop() e a função del. As sintaxes básicas de cada uma dessas maneiras de remover elementos de uma lista são mostradas a seguir:

<lista>.remove(<elemento>)
<lista>.pop(<índice>)
del <lista>[<índice>]
  • Método remove(<elemento>): remove o <elemento> da lista passado como parâmetro para o método. Se na lista existir mais de um elemento com o valor informado, será removido apenas a primeira ocorrência encontrada. Exemplos:

    disciplinas = ["Cálculo 1", "Programação I", "Algebra Linear"]
    disciplinas.remove("Cálculo 1")
    print(disciplinas) # ['Programação I', 'Algebra Linear']
    nomes = ["Ana", "Bia", "Ana", "Paula"]
    nomes.remove("Ana")
    print(nomes) # ['Bia', 'Ana', 'Paula']
    
  • Método pop(<índice>): remove o elemento da posição <índice>. Se o índice não for informado, o método removerá o último elemento da lista. Exemplos:

    disciplinas = ["Cálculo 1", "Programação I", "Algebra Linear"]
    disciplinas.pop(0)
    print(disciplinas) # ['Programação I', 'Algebra Linear']
    nomes = ["Ana", "Bia", "Ana", "Paula"]
    nomes.pop(1)
    print(nomes) # ['Ana', 'Ana', 'Paula']
    nomes.pop() # Remove o último elemento
    print(nomes) # ['Ana', 'Ana']
    
  • Função del <lista>[<índice>]: função integrada que remove o elemento da posição <índice> de <lista>. Se não for informado o índice da lista que se deseja remover o elemento, a função del destruirá a variável do tipo lista. Exemplos:

    disciplinas = ["Cálculo 1", "Programação I", "Algebra Linear"]
    del disciplinas[1]
    print(disciplinas) # ['Cálculo 1', 'Algebra Linear']
    

Por fim, se desejarmos esvaziar uma lista, podemos utilizar o método clear(), cuja sintaxe básica é a seguinte:

<lista>.clear()

Operador in

Quando precisamos verificar se determinado valor está em uma lista ou string, podemos usar o operador booleano in presente em Python. Tal operador retorna True se o elemento estiver na estrutura e False, caso contrário. Quando precisamos verificar se um valor não está em uma lista/string, podemos usar o operador not in. Se uso é bem simples:

L = [1, 2, 3, 4]
print(1 in L) # True
print(6 in L) # False
print(6 not in L) # True

Observe que o operador in é equivalente ao operador pertence da matemática (\(\in\)). Vejamos mais um exemplo:

def main():
    vogais = ['a', 'e', 'i', 'o', 'u']
    l = input("Digite uma letra: ")
    print("Vogal" if l in vogais else "Consoante")
    print("Consoante" if l not in vogais else "Vogal")

main()

Outro exemplo:

def main():
    alunosMatriculados = ['Paulo', 'Andre', 'Julio']
    aluno = input("Digite o nome do aluno: ")
    if aluno in alunosMatriculados:
        print(f"Aluno {aluno} está matriculado")
    else:
        print(f"Aluno {aluno} não está matriculado")
main()

Percorrendo uma lista

Quando uma lista possui poucos elementos, podemos acessar cada um de forma bem simples. Entretanto, quando uma lista possui vários elementos e precisamos imprimir ou fazer alguma análise/cálculo com os elementos precisamos de uma forma de acessar todos os elementos. Por exemplo, imagine que você tenha uma lista com a medida da temperatura de 365 dias e deseja saber (\(i\)) a temperatura média, (\(ii\)) a temperatura máxima, (\(iii\)) a temperatura mínima, (\(iv\)) o desvio padrão das temperaturas, (\(v\)) quantos dias a temperatura ficou acima (ou abaixo) da temperatura média, (\(vi\)) quais dias que a temperatura foi a máxima, etc. Note que para fazer essas operações temos que percorrer/acessar todos os elementos da lista. Para isso podemos utilizar o loop while ou for.

Usando while

Uma das formas de acessarmos cada um dos elementos da lista é iterando sobre os índices dos itens da lista, ou seja, primeiro acessamos o elemento da posição 0, depois da 1, e assim por diante, até o elemento de índice len(lista) - 1. Usando o loop while precisamos de uma variável que irá representar o índice que estamos acessando a lista em determinada iteração. O exemplo abaixo percorre a lista disciplinas e imprime, em cada linha, os elementos de tal lista.

1
2
3
4
5
6
7
8
disciplinas = ["Cálculo 1", "Programação I", "Algebra Linear"]
i = 0
while i < len(disciplinas): 
    print(disciplinas[i])
    i += 1
# Cálculo 1
# Programação I
# Algebra Linear

Pergunta

Por que a condição do loop while anterior foi i < len(disciplinas) e não i <= len(disciplinas)?

Usando for

Python apresenta uma estrutura de repetição especialmente projetada para percorrer listas. A instrução for funciona de forma parecida a while, mas a cada repetição utiliza um elemento diferente da lista. A instrução for itera sobre os itens de qualquer iterável (lista, tupla, dicionário, set ou string). Os itens são iterados na ordem em que aparecem no iterável. A sintaxe da instrução for é bem simples:

Loop for Fonte: Learn Python By Example

Na instrução for, <iterável> é uma coleção de objetos — por exemplo, uma lista ou tupla ou string. O corpo do loop é indicado pela indentação, como acontece com todas as estruturas de controle em Python e é executado uma vez para cada item em <iterável>. A variável de loop <var> assume o valor do próximo elemento em <iterável> cada vez que passa pelo loop. Veja um exemplo de um programa que imprime todos os elementos de uma lista:

1
2
3
4
5
6
disciplinas = ["Cálculo 1", "Programação I", "Algebra Linear"]
for d in disciplinas:
    print(d)
# Cálculo 1
# Programação I
# Algebra Linear

Embora a instrução for facilite nosso trabalho, ela não substitui completamente while. Dependendo do problema, utilizaremos for ou while. Normalmente utilizaremos for quando quisermos processar os elementos de uma lista, um a um. while é indicado para repetições nas quais não sabemos ainda quantas vezes vamos repetir ou onde manipulamos os índices de forma não sequencial.

Também podemos usar as instruções break e continue no loop for.

Função range

Podemos utilizar a função integrada range() para gerar uma lista/sequência de números entre o intervalo fornecido. A função range não retorna uma lista propriamente dita, mas um gerador ou generator. Por enquanto, basta entender como podemos usá-la. Veja um exemplo:

1
2
3
4
5
6
7
for i in range(5):
    print(i)
# 0
# 1
# 2
# 3
# 4

A função range gerou números de 0 a 4 porque passamos 5 como parâmetro. Ela normalmente gera valores a partir de 0, logo, ao especificarmos apenas 5, estamos apenas informando onde parar.

A função range() pode receber no máximo três argumentos:

range(start, stop, step) # (1)
  1. Os parâmetros start e step em range() são opcionais.

Onde start indica o valor inicial da sequência (parâmetro opcional cujo valor padrão é 0), stop valor final da sequência (parâmetro obrigatório), step representa o incremento da sequência (parâmetro opcional cujo valor padrão é 1).

  • range(stop) Ao chamar range() com apenas um argumento, teremos uma sequência de números de 0 até o número especificado.

    for i in range(5):
        print(i)
    # 0
    # 1
    # 2
    # 3
    # 4
    

    Observe que range(7) não são os valores de 0 a 7, mas sim os valores de 0 a 6.

  • range(start, stop) Por padrão, a função range() inicia o intervalo em 0. No entanto, podemos iniciar o intervalo com outro número adicionando o valor do parâmetro start.

    for i in range(2, 7):
        print(i)
    # 2
    # 3
    # 4
    # 5
    # 6
    
  • range(start, stop, step) Por padrão, na função range() o intervalo é incrementado em 1. No entanto, podemos especificar um incremento diferente adicionando o valor do parâmetro step.

    for i in range(2, 7, 2):
        print(i)
    # 2
    # 4
    # 6
    
    for i in range(0, 16, 3):
        print(i)
    # 0
    # 3
    # 6
    # 9
    # 12
    # 15
    

    Podemos percorrer os números na ordem inversa (decrementando) especificando um valor negativo para step.

    for i in range(6, 0, -1):
        print(i)
    # 6
    # 5
    # 4
    # 3
    # 2
    # 1
    

A função range retorna uma sequência imutável de números que pode ser facilmente convertida em listas, tuplas, etc. Para isso, utilizamos a função list():

L = list(range(7))
print(L)
# [0, 1, 2, 3, 4, 5, 6]

Função enumerate

Muitas vezes precisamos percorrer uma lista e obter, simultaneamente, seus elementos e os respectivos índices. Para isso, podemos utilizar a função enumerate() que, em geral, também é combinada com a estrutura de repetição for. Tal função gera uma tupla em que o primeiro valor é o índice e o segundo é o elemento da lista sendo enumerada. Veja como se pode utilizar enumerate() dentro de um for.

for <índice>, <elemento> enumerate(<lista>):
    <instruções>

Veja um exemplo:

1
2
3
4
5
6
7
8
alunos = ["Ana", "Beatriz", "Emanuel", "João", "Marcio"]
for indice, nome in enumerate(alunos):
    print(f"{nome} está armazenado no índice {indice}")
# Ana está armazenado no índice 0
# Beatriz está armazenado no índice 1
# Emanuel está armazenado no índice 2
# João está armazenado no índice 3
# Marcio está armazenado no índice 4

Como dito, a função enumerate() gera uma tupla. Veja o que acontece se usarmos apenas uma variável no for:

1
2
3
4
5
6
7
8
alunos = ["Ana", "Beatriz", "Emanuel", "João", "Marcio"]
for i in enumerate(alunos):
    print(i)
# (0, 'Ana')
# (1, 'Beatriz')
# (2, 'Emanuel')
# (3, 'João')
# (4, 'Marcio')

Embaralhando e Sorteando Elementos

Em algumas situações, é necessário escolher aleatoriamente um elemento dentro de uma lista. Um caso clássico dessa situação é um sorteio. Contudo, antes de realizar um sorteio, é realizado um embaralhamento das suas possíveis opções.

Para embaralhar os elementos de uma lista, utilizamos a função shuffle(<lista>) que, antes de ser executado, necessita que a biblioteca random seja importada. Para sortear um dos elementos da lista, utilizamos a função choice(<lista>). Veja um exemplo:

1
2
3
4
5
import random
L = list(range(7))
random.shuffle(L) # Embaralha os elementos na lista.
print(L)
print(random.choice(L)) # Escolhe um dos elementos da lista

Ordenando elementos

Para ordenar elementos de uma lista podemos usar o método sort(), cuja sintaxe básica é a seguinte:

<lista>.sort(reverse = [False | True])

onde o argumento reverse indica se haverá inversão (reverse = True) ou se não haverá (reverse = False). Por padrão, o valor desse parâmetro é False (ordenação crescente) e, portanto, o argumento reverse pode ser omitido. Veja um exemplo:

1
2
3
4
5
L = [7,4,3,12,8]
L.sort()
print(L) # [3, 4, 7, 8, 12]
L.sort(reverse = True) 
print(L) # [12, 8, 7, 4, 3]

Também podemos usar a função integrada sorted para obter uma cópia ordenada de uma lista, sem alterar a lista original.

1
2
3
L = [7, 4, 3, 12, 8]
print(sorted(L)) # [3, 4, 7, 8, 12]
print(L) # [7, 4, 3, 12, 8]

Concatenando listas

Podemos usar o operador + para concatenar (juntar) duas listas. Por exemplo:

1
2
3
4
lista1 = [2, 4, 8]
lista2 = [1, 3, 5]
lista3 = lista1 + lista2
print(lista3) # [2, 4, 8, 1, 3, 5]

Também podemos usar o operador de atribuição += para concatenar uma lista a outra. Por exemplo:

1
2
3
4
lista1 = [2, 4, 8]
lista2 = [1, 3, 5]
lista1 += lista2 # Equivalente à lista1 = lista1 + lista2
print(lista1) # [2, 4, 8, 1, 3, 5]

Quando precisamos replicar uma lista n vezes, podemos usar o operador * (que funciona de forma equivalente com string).

1
2
3
4
5
l = [0]*3
print(l) # [0, 0, 0]
n = [1, 2, 3]*2
print(n) # [1, 2, 3, 1, 2, 3]
print(["ola"]*2) # ["ola", "ola"]

Vejamos um exemplo simples de como podemos fazer a leitura de duas notas:

1
2
3
4
5
notas = []
x = float(input("Nota: "))
notas += [x] # Note que o x deve estar entre colchetes
x = float(input("Nota: "))
notas += [x]

Note que se o número de notas a ser lido for grande ou se não soubermos a quantidade de notas, devemos usar uma estrutura de repetição para ler as notas e retornar uma lista com as notas.

Vamos fazer uma função que receba a quantidade de notas a ser lida e retorna uma lista de notas, usando concatenação.

1
2
3
4
5
6
def leNotas(n):
    notas = []
    while len(notas) != n:
        x = float(input("Nota: "))
        notas += [x]
    return notas

A função leNotas pode ser feita de diversas outras maneiras. Pense em outras formas de implementar tal função.

Exercício

Modifique a função para que as notas sejam lidas enquanto não for digitado um valor negativo.

Fatiamento

Com a indexação podemos selecionar um elemento específico em uma lista. Entretanto, às vezes, precisamos selecionar mais de um elemento de uma lista. Em Python, podemos escrever expressões que selecionam sublistas de uma lista, conhecidas como fatias.

Uma fatia é um intervalo de itens retornados de uma lista. Quando pegamos uma fatia de uma lista, obtemos um intervalo de elementos da lista. Se L for uma lista, a expressão L[<inicio>:<fim>:<salto>] retorna a parte da lista do índice <inicio> até o índice <fim>, saltando <salto> elementos. O parâmetro <salto> é opcional e, por padrão, vale 1.

No formato geral, <inicio> é o índice do primeiro elemento do fatiamento e <fim> é o índice que marca o fim da fatia. A expressão retorna uma lista contendo uma cópia dos elementos desde o <inicio> até (mas não incluindo) o <fim>. Por exemplo:

L = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
print(L[2:7]) # ['c', 'd', 'e', 'f', 'g']

A figura abaixo ilustra a operação L[2:7]:

Fatiamento Fonte: Learn Python By Example

Note que o item no índice 7 (que contém 'h') não está incluído no fatiamento anterior.

Se você deixar em branco o valor de <inicio> em um fatiamento, será usado 0 como o índice inicial. Veja alguns exemplos:

1
2
3
4
5
6
L = [0, 1, 2, 3, 4, 5, 6]
print(L[:3]) # [0, 1, 2] equivalente à print(L[0:3])
print(L[:-2]) # [0, 1, 2, 3, 4]
print(L[:len(L)] # [0, 1, 2, 3, 4, 5, 6]
print(L[:1]) # [0]
print(L[:0]) # []

Se você deixar em branco o valor de <fim> em um fatiamento, será usado o tamanho da lista como o índice final. Por exemplo:

1
2
3
4
5
L = [0, 1, 2, 3, 4, 5, 6]
print(L[3:]) # [3, 4, 5, 6] equivalente à print(L[3:len(L)])
print(L[-2:]) # [5, 6]
print(L[-1:]) # [6]
print(L[len(L):]) # []

Se você deixar em branco o valor de <inicio> e <fim> em um fatiamento, você obterá uma cópia da lista inteira. Exemplo:

L = [0, 1, 2, 3, 4, 5, 6]
print(L[:]) # [0, 1, 2, 3, 4, 5, 6] equivalente à print(L[0:len(L)])

Os exemplos de fatiamento que vimos até agora obtêm fatias de elementos consecutivos das listas. Expressões de fatiamento também podem ter um valor de "salto" (step), o que pode fazer com que algumas posições sejam ignoradas na lista. Por exemplo:

L = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
print(L[2:7:2]) # ['c', 'e', 'g']

Fatiamento Fonte: Learn Python By Example

Vejamos mais alguns exemplos:

1
2
3
4
5
6
L = [0, 1, 2, 3, 4, 5, 6]
print(L[0:5:2]) # [0, 2, 4] 
print(L[0:5:1]) # [0, 1, 2, 3, 4]
print(L[::2]) # [0, 2, 4, 6]
print(L[::-1]) # [6, 5, 4, 3, 2, 1, 0]
print(L[::-2]) # [6, 4, 2, 0]

Vale destacar que índices inválidos em um fatiamento não geram erros. Por exemplo:

  • Se o índice final for uma posição além do final da lista, será usado o tamanho da lista:

    L = [0, 1, 2, 3, 4, 5, 6]
    print(L[0:20]) # [0, 1, 2, 3, 4, 5, 6]
    
  • Se o índice inicial for uma posição antes do início da lista, será usando o valor 0:

    L = [0, 1, 2, 3, 4, 5, 6]
    print(L[-20:]) # [0, 1, 2, 3, 4, 5, 6]
    
  • Se o índice inicial for maior que o índice final, a expressão fatiada retornará uma lista vazia:

    L = [0, 1, 2, 3, 4, 5, 6]
    print(L[20:]) # []
    

Cópia de listas

Um dos efeitos colaterais de lista aparece quando tentamos fazer cópias. Por exemplo:

1
2
3
4
5
6
7
L = [0, 1, 2, 3, 4]
V = L
print(L) # [1, 2, 3, 4]
print(V) # [1, 2, 3, 4]
V[0] = 6
print(V) # [6, 2, 3, 4]
print(L) # [6, 2, 3, 4]

Veja que, ao modificarmos V, modificamos também o conteúdo de L. Isso porque uma lista em Python é um objeto e, quando atribuímos um objeto a outro, estamos apenas copiando a mesma referência da lista, e não seus dados. Nesse caso, V funciona como um apelido de L, ou seja, V e L são a mesma lista. Dessa forma, quando modificamos V[0], estamos modificando o mesmo valor de L[0], pois ambos são referências, ou apelidos, para a mesma lista na memória.

Dependendo da aplicação, esse efeito pode ser desejado ou não. Para criarmos uma cópia independente de uma lista, temos três alternativas:

  • Concatenação com uma lista vazia ([]):
1
2
3
4
5
6
7
L = [0, 1, 2, 3, 4]
V = L + [] # ou V = [] + L
print(L) # [1, 2, 3, 4]
print(V) # [1, 2, 3, 4]
V[0] = 6
print(V) # [6, 2, 3, 4]
print(L) # [0, 2, 3, 4]
  • Fatiamento:
1
2
3
4
5
6
7
L = [0, 1, 2, 3, 4]
V = L[:] 
print(L) # [1, 2, 3, 4]
print(V) # [1, 2, 3, 4]
V[0] = 6
print(V) # [6, 2, 3, 4]
print(L) # [0, 2, 3, 4]

Ao escrevermos L[:], estamos nos referindo a uma nova cópia de L (lembre-se que fatiamento sempre retorna uma cópia). Assim, L e V se referem a áreas diferentes na memória, permitindo alterá-las de forma independente.

  • Método copy():
1
2
3
4
5
6
7
L = [0, 1, 2, 3, 4]
V = L.copy() 
print(L) # [1, 2, 3, 4]
print(V) # [1, 2, 3, 4]
V[0] = 6
print(V) # [6, 2, 3, 4]
print(L) # [0, 2, 3, 4]

Listas aninhadas

Uma lista pode conter qualquer objeto, até mesmo outra lista (sublista), que por sua vez pode conter as outras sublistas e assim por diante. Isso é conhecido como lista aninhada (do inglês, nested list). Você pode usá-las para organizar os dados em estruturas hierárquicas. Por exemplo:

L = ['a', 'b', ['cc', 'dd', ['eee', 'fff']], 'g', 'h']

Podemos acessar itens individuais em uma lista aninhada usando os subíndices. Os índices para os itens da lista aninhada anterior são ilustrados a seguir:

Listas Aninhadas Fonte: Learn Python By Example

1
2
3
4
L = ['a', 'b', ['cc', 'dd', ['eee', 'fff']], 'g', 'h']
print(L[2]) # ['cc', 'dd', ['eee', 'fff']]
print(L[2][2]) # ['eee', 'fff']
print(L[2][2][0]) # eee

Podemos modificar o valor de um item específico em uma lista aninhada através do índice.

1
2
3
4
5
L = ['a', ['bb', 'cc'], 'd']
L[1][1] = 0
print(L) # ['a', ['bb', 0], 'd']
L[1] = 'b'
print(L) ['a', 'b', 'd']

Para adicionar um novo elemento no fim de uma lista aninhada, podemos usar o método append().

1
2
3
4
5
L = ['a', ['bb', 'cc'], 'd']
L.append('e')
print(L) # ['a', ['bb', 'cc'], 'd', 'e]
L[1].append('xx')
print(L) # ['a', ['bb', 'cc', 'xx'], 'd']

A função integrada len() também é usada para descobrir quantos itens uma sublista aninhada possui:

1
2
3
L = ['a', ['bb', 'cc'], 'd']
print(len(L)) # 3
print(len(L[1])) # 2

Se precisarmos percorrer todos os elementos de uma lista aninhada, podemos usar um loop for:

1
2
3
4
5
6
L = [[1, 2, 3],[4, 5, 6],[7, 8, 9]]   
for x in L:
    print(x)
# [1, 2, 3]
# [4, 5, 6]
# [7, 8, 9]

Perceba que em cada linha foi impresso uma lista. Normalmente, queremos acessar cada uma dos elementos da lista aninhada de forma "independente". Para isso, precisamos ter um for aninhado que fica responsável por iterar sobre os elementos de cada sublista:

1
2
3
4
5
6
7
8
L = [[1, 2, 3],[4, 5, 6],[7, 8, 9]]   
for lista in L:
    for numero in lista:
        print(numero, end=' ')
    print()
# 1 2 3 
# 4 5 6 
# 7 8 9

Outra alternativa usando a função range():

1
2
3
4
5
6
7
8
L = [[1, 2, 3],[4, 5, 6],[7, 8, 9]] 
for i in range(len(L)):
    for j in range(len(L[i])):
        print(L[i][j], end=' ')
    print()
# 1 2 3 
# 4 5 6 
# 7 8 9

Compreensão de listas

Compreensão de listas (list comprehensions) é uma maneira elegante e compacta de criar listas com base em listas existentes.

Vejamos um exemplo, suponha que precisamos criar uma lista de todos os números inteiros quadrados de 0 a 4. Podemos construir essa lista incluindo um item de cada vez a uma lista vazia:

1
2
3
4
5
6
7
L = []
L.append(0)
L.append(1)
L.append(4)
L.append(9)
L.append(16)
print(L) # [0, 1, 4, 9, 16]

Outra alternativa é usar um loop:

1
2
3
4
L = []
for x in range(5):
    L.append(x**2)
print(L) # [0, 1, 4, 9, 16]

Aqui ambas as abordagens produzem o mesmo resultado. No entanto, uma maneira mais Pythonica de construir uma lista é usando uma compreensão de lista.

A sintaxe geral para a compreensão de lista é:

Compreensão de listas Fonte: Learn Python By Example

Veja como podemos usar compreensão de lista para construir a lista anterior:

L = [x**2 for x in range(5)]
print(L) # [0, 1, 4, 9, 16]

Abaixo são apresentados outros exemplos de compreensão de listas.

  1. Compreensão de lista pode iterar em qualquer tipo de iterável, como listas e strings. Veja um exemplo de uma compreensão de lista simples que usa string como um iterável.

    L = [x*3 for x in "ABC"]
    print(L) # ["AAA", "BBB", "CCC"]
    
  2. O exemplo a seguir aplica a função abs() a todos os elementos em uma lista.

    L = [abs(x) for x in [-2, -1, 0, 1, 2, 3]]
    print(L) # [2, 1, 0, 1, 2, 3]
    
  3. O exemplo abaixo cria uma lista, usando expressão ternária, onde a posição i contém a string "Par" se i for par e "Impar", caso contrário.

    L = ["Par" if i % 2 == 0 else "Impar" for i in range(6)]
    print(L) # ['Par', 'Impar ', 'Par', 'Impar ', 'Par', 'Impar ']
    
  4. O exemplo abaixo cria uma lista contendo a raiz quadrada de cada número.

    L = [math.sqrt(x) for x in [abs(i) for i in [-4, -16 , -64 , -256]]]
    print(L) # [2.0, 4.0, 8.0, 16.0]
    

    Note que nesse exemplo, primeiro foi criado uma lista (usando compreensão de lista) aplicando a função abs() em cada elemento de [-4, -16 , -64 , -256]. Dessa forma, teremos a lista [4, 16 , 64 , 256]. Com essa última lista é aplicado a função raiz quadrada (math.sqrt()).

  5. O exemplo abaixo faz a leitura de vários valores da entrada, digitados na mesma linha, e cria uma lista com cada valor convertido para inteiro.

    L = [int(x) for x in input().split()] # Suponha que a entrada seja: 1 2 3 4 5
    print(L) # [1, 2, 3, 4, 5]
    
  6. O exemplo abaixo cria uma lista aninhada onde cada elemento é uma lista da forma [x, x**2], para \(0 \leq x \leq 5\).

    L = [[x, x**2] for x in range(6)] 
    print(L) # [[0, 0], [1, 1], [2, 4], [3, 9], [4, 16], [5, 25]]
    

Compreensão de lista com cláusula if

Uma compreensão de lista pode ter uma cláusula if opcional associada para filtrar itens do resultado. Os itens do iterável para os quais a cláusula if não é verdadeira são ignorados. A sintaxe é bem simples:

Compreensão de listas com cláusula if Fonte: Learn Python By Example

Vejamos alguns exemplos:

  1. Dada uma lista com diversos valores inteiros, criar uma lista com apenas os elementos maiores ou iguais a zero de tal lista.

    L = [x for x in [-2, -1, 0, 1, 2, 3] if x >= 0]
    print(L) # [0, 1, 2, 3]
    
  2. Dada uma lista com diversos valores de tipos variados, criar uma lista onde os elementos inteiros de tal lista são elevados ao quadrado.

    L = [x**2 for x in [1, 2, 'a', 3, 4.0] if isinstance(x, int)]
    print(L) # [1, 4, 9]
    

Listas e funções puras

Como as variáveis do tipo list são mutáveis, devemos tomar alguns cuidados ao usar funções que contém uma ou mais listas como parâmetros e que modificam essa(s) lista(s). Vamos a um exemplo:

def modificaLista(lista, posicao, valor):
    lista[posicao] = valor

def adicionaElemento(lista, valor):
    lista.append(valor)

def main():
    L = [0, 1, 2, 3]
    print(L) # [0, 1, 2, 3]
    modificaLista(L, 1, 45)
    print(L) # [0, 45, 2, 3]
    adicionaElemento(L, 23)
    print(L) # [0, 45, 2, 3, 23]

main()

Note que após a chamada da função modificaLista, a lista L sofreu uma alteração externa, ou seja, a alteração feita em modificaLista persistiu após a chamada da função (efeito colateral). De forma resumida, isso acontece porque Python passa o endereço da memória onde a lista está armazenada e não uma cópia dela (como acontece com as variáveis do tipo int e float, por exemplo). Por isso, modificaLista é considerada uma função impura. O mesmo acontece com a função adicionaElemento. Para não restar dúvidas, teste o código no Python Tutor.

Note que tanto a lista L (da função main) quanto lista (das funções modificaLista e adicionaElemento) "apontam" para o mesmo objeto, ou seja, se modificamos um, iremos modificar o outro também. Dessa forma, a modificação nas funções modificaLista e adicionaElemento persiste após a execução da função, o que vai contra a ideia de funções puras.

Para resolvermos esse "problema", basta passar uma cópia da lista para a função, ou seja, devemos chamar a função da seguinte forma: modificaLista(L[:], 1, 45) e adicionaElemento(L[:], 23) (ou modificaLista(L.copy(), 1, 45) e adicionaElemento(L.copy(), 23)). Teste o código modificado no Python Tutor e veja o resultado.

Agora temos duas listas independentes, consequentemente, a modificação na função modificaLista e/ou adicionaElemento não persiste após a execução da função.

Métodos em listas

Abaixo são listados os métodos dos objetos do tipo lista:

Método Descrição
append() Adiciona um item ao final da lista
insert() Insere um item em uma determinada posição
extend() Estende a lista anexando todos os itens do iterável
remove() Remove a primeira instância do item especificado
pop() Remove o item na posição especificada na lista
clear() Remove todos os itens da lista
copy() Retorna uma cópia da lista
count() Retorna a contagem do item especificado na lista
index() Retorna o índice da primeira instância do item especificado
reverse() Inverte os itens da lista
sort() Ordena os itens da lista

Funções integradas para listas

Python também possui um conjunto de funções integradas que podemos usar com objetos do tipo lista.

Método Descrição
all() Retorna True se todos os itens da lista forem verdadeiros
any() Retorna True se algum item da lista for verdadeiro
enumerate() Pega uma lista e retorna um objeto enumerado
len() Retorna o número de itens da lista
list() Converte um iterável (tupla, string, set etc.) em uma lista
max() Retorna o maior item da lista
min() Retorna o menor item da lista
sorted() Retorna uma lista ordenada
sum() Soma os itens da lista