Uma list é uma coleção mutável de itens em sequência.
Como a maioria das coleções (veja os tipos embutidos tuple, dict e set), as listas podem guardar referências a qualquer tipo de dado (ou a vários), inclusive outras listas.
Em Python, elas são consideradas uma sequência e podem ser copiadas por inteiro ou em parte com a notação de fatiamento.
Como qualquer sequência, os elementos dentro de lists podem ser referenciados por um número de 0-based index a partir da esquerda, ou de -1-based index a partir da direita.
As listas suportam tanto operações comuns de sequência quanto operações de sequência mutáveis, como min(<list>)/max(<list>), <list>.index(), <list>.append() e <list>.reverse().
Pode-se iterar sobre os itens com a construção for item in <list>, e com for index, item in enumerate(<list>) quando você precisa tanto do elemento quanto do índice dele.
O Python oferece muitos métodos úteis para trabalhar com listas.
Como as listas são mutáveis, os métodos de lista alteram o objeto de lista original passado para o método.
Se a mutação não for desejada, é preciso criar uma shallow copy (no mínimo) da list original, com slice ou <list>.copy().
Você pode adicionar itens ao final de uma lista existente com <list>.append(<item>):
>>> numbers = [1, 2, 3]
>>> numbers.append(9)
>>> numbers
[1, 2, 3, 9]
Em vez de acrescentar ao final, <list>.insert(<index>, <item>) adiciona o item a um índice específico dentro da lista.
<index> é o índice do item antes do qual você quer que o novo item apareça.
<item> é o elemento a ser inserido.
Observação: Se <index> for 0, o item será adicionado ao início da lista.
Se <index> for maior que o índice final da lista, o item será adicionado na posição final, o equivalente a usar <list>.append(<item>).
>>> numbers = [1, 2, 3]
>>> numbers.insert(0, -2)
>>> numbers
[-2, 1, 2, 3]
>>> numbers.insert(1, 0)
>>> numbers
[-2, 0, 1, 2, 3]
Um iterable pode ser combinado com uma lista existente (concatenando os dois) com <list>.extend(<iterable>).
<list>.extend(<iterable>) desempacota o iterable fornecido, adicionando seus elementos na mesma ordem ao final da lista de destino.
Usar <list>.append(<item>) nessa situação adicionaria o iterable inteiro como um único item.
>>> numbers = [1, 2, 3]
>>> other_numbers = [5, 6, 7]
>>> numbers.extend(other_numbers)
>>> numbers
[1, 2, 3, 5, 6, 7]
>>> numbers.extend([8, 9])
>>> numbers
[1, 2, 3, 5, 6, 7, 8, 9]
Você pode usar <list>.remove(<item>) para remover um elemento da lista.
<list>.remove(<item>) lança um ValueError se o elemento não estiver presente na lista.
>>> numbers = [1, 2, 3]
>>> numbers.remove(2)
>>> numbers
[1, 3]
# Trying to remove a value that is not in the list throws a ValueError.
>>> numbers.remove(0)
ValueError: list.remove(x): x not in list
Como alternativa, o método <list>.pop(<index>) remove e return um elemento para uso.
<list>.pop(<index>) recebe um parâmetro opcional: o index do elemento a remover e retornar.
Se o argumento opcional <index> não for especificado, o último elemento da lista será removido e retornado.
Se <index> for um número maior que o índice final da lista, um IndexError será lançado.
>>> numbers = [1, 2, 3]
>>> numbers.pop(0)
1
>>> numbers
[2, 3]
>>> numbers.pop()
3
>>> numbers
[2]
# This will throw an error because there is only index 0.
>>> numbers.pop(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: pop index out of range
Você pode remover todos os itens de uma list com <list>.clear(). Ele não recebe nenhum parâmetro.
>>> numbers = [1, 2, 3]
>>> numbers.clear()
>>> numbers
[]
A ordem dos elementos de uma lista pode ser invertida no próprio lugar com <list>.reverse(). Isso modifica a lista original.
>>> numbers = [1, 2, 3]
>>> numbers.reverse()
>>> numbers
[3, 2, 1]
Uma lista pode ser reordenada no próprio lugar com a ajuda de <list>.sort().
Por padrão, a ordenação é crescente, da esquerda para a direita.
A documentação do Python oferece dicas e técnicas adicionais de ordenação.
De 2002 a 2022, o Python usou internamente um algoritmo chamado Timsort para organizar listas, mas passou a usar o Powersort a partir do Python 3.11.
Você pode ler mais detalhes e discussões sobre a mudança na equipe principal do Python no issue 78742 do GitHub.
Para detalhes técnicos sobre o algoritmo, veja o artigo de J. Ian Munro e Sebastian Wild, Nearly-Optimal Mergesorts: Fast, Practical Sorting Methods That Optimally Adapt to Existing Runs
>>> names = ["Tony", "Natasha", "Thor", "Bruce"]
# The default sort order is *ascending*.
>>> names.sort()
>>> names
["Bruce", "Natasha", "Thor", "Tony"]
Para ordenar uma lista em ordem decrescente, passe o argumento reverse=True para o método:
>>> names = ["Tony", "Natasha", "Thor", "Bruce"]
>>> names.sort(reverse=True)
>>> names
["Tony", "Thor", "Natasha", "Bruce"]
Quando você não quer modificar a list original, pode usar as funções embutidas sorted() e reversed().
sorted(<list>) retorna uma cópia ordenada e aceita os mesmos parâmetros que <list>.sort().
reversed(<list>) retorna um iterator que produz os itens da lista em ordem inversa.
Os Iterators serão abordados em detalhe em outro exercício.
Você pode descobrir o número de ocorrências de um elemento em uma lista com <list>.count(<item>).
Ele retorna o número total de vezes que <item> aparece como elemento na lista.
>>> items = [1, 4, 7, 8, 2, 9, 2, 1, 1, 0, 4, 3]
>>> items.count(1)
3
<list>.index(<item>) retorna o número do índice da primeira ocorrência do item informado.
Se não houver ocorrências, um ValueError é lançado.
A indexação é 0-based a partir da esquerda, ou seja, a posição do primeiro item é o índice 0.
A indexação a partir da direita também é suportada, começando pelo índice -1.
>>> items = [7, 4, 1, 0, 2, 5]
>>> items.index(4)
1
>>> items.index(10)
ValueError: 10 is not in list
Informar os índices start e end faz a busca acontecer dentro de uma seção específica da lista:
>>> names = ["Tina", "Leo", "Thomas", "Tina", "Emily", "Justin"]
>>> names.index("Tina")
0
>>> names.index("Tina", 2, 5)
3
Se você não precisa da posição exata de um elemento, o operador embutido in é mais eficiente para verificar se ele pertence à lista.
>>> names = ["Tina", "Leo", "Thomas", "Tina", "Emily", "Justin"]
>>> "Thomas" in names
True
Lembre-se de que as variáveis em Python são nomes que apontam para objetos subjacentes.
Os nomes podem ser vinculados ou revinculados a objetos diferentes ao longo da vida de um programa.
Atribuir um objeto list a um novo nome de variável não copia o objeto nem nenhum dos dados referenciados por ele.
O novo nome e o nome antigo vão apontar para o mesmo objeto list.
Além disso, as listas são um objeto do tipo container e, para economizar espaço, os containers guardam apenas referências aos itens que contêm, não os próprios itens.
Essa "otimização" pode ter consequências indesejadas para quem não presta atenção.
<list>.copy() cria um novo objeto list, mas não cria novos objetos para os elementos referenciados da lista: a cópia é "superficial".
Uma shallow copy normalmente basta quando você quer adicionar ou remover itens de um dos objetos list sem modificar o outro.
Mas se houver qualquer chance de os elementos subjacentes de uma list serem modificados por acidente (e assim modificarem todas as cópias superficiais relacionadas), você deve usar copy.deepcopy(), do módulo copy, para criar uma cópia completa, ou "profunda", de todas as referências e objetos.
Para uma explicação detalhada sobre nomes, valores, listas e o comportamento de listas aninhadas, dê uma olhada neste excelente post do blog do Ned Batchelder: Names and values: making a game board. Shallow vs Deep Copying of Python Objects também traz um bom resumo sobre as considerações de cópia.