Listas são uma das estruturas de dados mais versáteis e amplamente utilizadas em Python. Elas permitem armazenar uma coleção ordenada de itens, que podem ser de diferentes tipos, e oferecem uma vasta gama de operações para manipulação. Nesta aula, exploraremos desde a criação e acesso até técnicas avançadas como fatiamento e métodos embutidos, além de entender a mutabilidade das listas.

Dominar listas é fundamental para qualquer programador Python, pois elas são a base para muitas outras estruturas de dados e algoritmos. Vamos começar!

Criação e acesso

As listas em Python são criadas utilizando colchetes [] ou a função list(). Os elementos são separados por vírgulas. Por exemplo:

frutas = ['maçã', 'banana', 'laranja']
print(frutas)  # ['maçã', 'banana', 'laranja']

# Usando list()
numeros = list(range(5))
print(numeros)  # [0, 1, 2, 3, 4]

O acesso aos elementos é feito por índices, que começam em 0. Índices negativos contam a partir do final da lista.

frutas = ['maçã', 'banana', 'laranja']
print(frutas[0])   # maçã
print(frutas[-1])  # laranja

Também é possível modificar um elemento específico atribuindo um novo valor a seu índice:

frutas[1] = 'morango'
print(frutas)  # ['maçã', 'morango', 'laranja']

Listas podem conter elementos de tipos diferentes, inclusive outras listas (listas aninhadas).

mista = [1, 'dois', 3.0, [4, 5]]
print(mista[3][0])  # 4

Fatiamento

O fatiamento (slicing) permite extrair uma sublista a partir de uma lista original. A sintaxe é lista[início:fim:passo], onde início é o índice inicial (inclusivo), fim é o índice final (exclusivo) e passo é o incremento. Todos os parâmetros são opcionais.

numeros = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(numeros[2:5])   # [2, 3, 4]
print(numeros[:3])    # [0, 1, 2]
print(numeros[5:])    # [5, 6, 7, 8, 9]
print(numeros[::2])   # [0, 2, 4, 6, 8]
print(numeros[::-1])  # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

O fatiamento cria uma nova lista, não modifica a original. É uma operação muito útil para cópias parciais ou para reverter listas.

Métodos (append, extend, etc.)

As listas possuem diversos métodos embutidos que facilitam sua manipulação. Aqui estão os principais:

  • append(x): adiciona o elemento x ao final da lista.
  • extend(iterável): adiciona todos os itens do iterável ao final da lista.
  • insert(i, x): insere x na posição i.
  • remove(x): remove a primeira ocorrência de x.
  • pop([i]): remove e retorna o elemento na posição i (ou o último se omitido).
  • index(x): retorna o índice da primeira ocorrência de x.
  • count(x): retorna o número de ocorrências de x.
  • sort(): ordena a lista in-place.
  • reverse(): inverte a ordem dos elementos in-place.
  • copy(): retorna uma cópia rasa da lista.

Exemplos:

lista = [1, 2, 3]
lista.append(4)
print(lista)  # [1, 2, 3, 4]

lista.extend([5, 6])
print(lista)  # [1, 2, 3, 4, 5, 6]

lista.insert(0, 0)
print(lista)  # [0, 1, 2, 3, 4, 5, 6]

lista.remove(3)
print(lista)  # [0, 1, 2, 4, 5, 6]

ultimo = lista.pop()
print(ultimo)  # 6
print(lista)   # [0, 1, 2, 4, 5]

indice = lista.index(4)
print(indice)  # 3

contagem = lista.count(2)
print(contagem)  # 1

lista.sort()
print(lista)  # [0, 1, 2, 4, 5]

lista.reverse()
print(lista)  # [5, 4, 2, 1, 0]

copia = lista.copy()
print(copia)  # [5, 4, 2, 1, 0]

Mutabilidade

Listas são mutáveis, ou seja, seus elementos podem ser alterados após a criação. Isso as diferencia de tuplas, que são imutáveis. A mutabilidade permite modificar a lista in-place, como vimos nos métodos append, sort, etc.

Porém, é importante ter cuidado com referências compartilhadas. Quando atribuímos uma lista a outra variável, ambas apontam para o mesmo objeto, e modificações em uma afetam a outra.

a = [1, 2, 3]
b = a
b.append(4)
print(a)  # [1, 2, 3, 4] (a foi modificado!)

# Para criar uma cópia independente, use copy() ou fatiamento
c = a.copy()
c.append(5)
print(a)  # [1, 2, 3, 4]
print(c)  # [1, 2, 3, 4, 5]

Além disso, ao passar listas como argumentos para funções, a função pode modificar a lista original, a menos que seja feita uma cópia explícita.

def adiciona_elemento(lista):
    lista.append(99)

minha_lista = [1, 2]
adiciona_elemento(minha_lista)
print(minha_lista)  # [1, 2, 99]

Boas práticas

  • Use list.append() em vez de list += [item] para adicionar um único elemento, pois é mais eficiente.
  • Evite modificar uma lista enquanto a itera sobre ela; crie uma cópia se necessário.
  • Para remover elementos durante iteração, itere sobre uma cópia: for item in lista[:]:
  • Preferir list comprehension para criar novas listas de forma concisa: [x**2 for x in range(10)].

Referências

Exercícios

  1. Crie uma lista chamada numeros com os números de 1 a 10. Em seguida, extraia uma sublista com os números pares usando fatiamento.

    ✓ Resposta:
    numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    pares = numeros[1::2]  # começa no índice 1 (valor 2) e passo 2
    print(pares)  # [2, 4, 6, 8, 10]
  2. Dada a lista frutas = ['maçã', 'banana', 'laranja'], adicione 'uva' ao final, insira 'morango' na posição 1 e remova 'banana'. Imprima a lista final.

    ✓ Resposta:
    frutas = ['maçã', 'banana', 'laranja']
    frutas.append('uva')
    frutas.insert(1, 'morango')
    frutas.remove('banana')
    print(frutas)  # ['maçã', 'morango', 'laranja', 'uva']
  3. Explique por que o código abaixo modifica a lista original e como evitar isso.

    original = [1, 2, 3]
    copia = original
    copia.append(4)
    print(original)  # [1, 2, 3, 4]

    ✓ Resposta:Isso acontece porque copia = original não cria uma nova lista, apenas faz copia referenciar o mesmo objeto. Para evitar, use copia = original.copy() ou copia = original[:].
  4. Utilizando métodos de lista, inverta a ordem dos elementos de lista = [1, 2, 3, 4, 5] e depois ordene em ordem decrescente.

    ✓ Resposta:
    lista = [1, 2, 3, 4, 5]
    lista.reverse()
    print(lista)  # [5, 4, 3, 2, 1]
    lista.sort(reverse=True)
    print(lista)  # [5, 4, 3, 2, 1] (já está, mas para demonstrar)
  5. Crie uma lista de números de 1 a 5. Use o método pop para remover o último elemento e armazená-lo em uma variável. Em seguida, use extend para adicionar os números [6, 7] ao final. Mostre a lista resultante.

    ✓ Resposta:
    numeros = [1, 2, 3, 4, 5]
    ultimo = numeros.pop()
    print(ultimo)  # 5
    numeros.extend([6, 7])
    print(numeros)  # [1, 2, 3, 4, 6, 7]