Listas: criando, acessando e modificando

1. Introdução às listas em Python

Listas são uma das estruturas de dados mais fundamentais e versáteis em Python. Elas representam coleções ordenadas e mutáveis de elementos, permitindo armazenar múltiplos valores em uma única variável. Diferentemente de tuplas (imutáveis) e dicionários (baseados em chaves), as listas podem ser modificadas após sua criação — você pode adicionar, remover ou alterar elementos livremente.

A principal diferença entre listas e tuplas é a mutabilidade: listas podem ser alteradas, tuplas não. Já os dicionários armazenam pares chave-valor, enquanto listas armazenam elementos indexados por posição.

No dia a dia, usamos listas para representar coleções como:
- Lista de compras do supermercado
- Notas de alunos em uma turma
- Pontos em um gráfico
- Nomes de arquivos em um diretório
- Resultados de uma pesquisa

2. Criando listas

A sintaxe básica para criar uma lista é simples: use colchetes [] e separe os elementos por vírgula.

# Lista homogênea (mesmo tipo)
numeros = [1, 2, 3, 4, 5]
nomes = ["Ana", "Bruno", "Carla"]

# Lista heterogênea (tipos diferentes)
mista = [42, "Python", True, 3.14]

# Lista vazia
vazia = []
outra_vazia = list()

# Lista aninhada (matriz)
matriz = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

print(numeros)      # [1, 2, 3, 4, 5]
print(mista)        # [42, 'Python', True, 3.14]
print(matriz)       # [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

Listas podem conter qualquer tipo de objeto Python, incluindo outras listas, criando estruturas multidimensionais.

3. Acessando elementos

O acesso aos elementos é feito através de índices, que começam em 0 para o primeiro elemento.

frutas = ["maçã", "banana", "laranja", "uva", "manga"]

# Índices positivos (do início)
print(frutas[0])    # maçã
print(frutas[2])    # laranja
print(frutas[4])    # manga

# Índices negativos (do final)
print(frutas[-1])   # manga (último)
print(frutas[-3])   # laranja (terceiro do final)
print(frutas[-5])   # maçã (primeiro)

# Erro comum: IndexError
# print(frutas[10])  # IndexError: list index out of range

Para evitar IndexError, sempre verifique o tamanho da lista antes de acessar:

if len(frutas) > 10:
    print(frutas[10])
else:
    print("Índice fora do intervalo")

Acessando elementos de listas aninhadas:

matriz = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

print(matriz[0][1])     # 2 (linha 0, coluna 1)
print(matriz[2][2])     # 9 (linha 2, coluna 2)
print(matriz[1][0])     # 4 (linha 1, coluna 0)

4. Modificando elementos

A mutabilidade das listas permite alterar elementos diretamente por atribuição:

cores = ["vermelho", "verde", "azul"]
print(cores)            # ['vermelho', 'verde', 'azul']

# Atribuição direta
cores[1] = "amarelo"
print(cores)            # ['vermelho', 'amarelo', 'azul']

# Atribuição de fatia (slice assignment)
numeros = [1, 2, 3, 4, 5]
numeros[1:4] = [20, 30, 40]
print(numeros)          # [1, 20, 30, 40, 5]

Cuidado com referências! Ao atribuir uma lista a outra variável, ambas apontam para o mesmo objeto:

lista_a = [1, 2, 3]
lista_b = lista_a       # Não é uma cópia, é a mesma lista

lista_b[0] = 999
print(lista_a)          # [999, 2, 3] (modificou também lista_a!)

5. Adicionando elementos

Python oferece vários métodos para adicionar elementos a uma lista:

tarefas = ["estudar", "trabalhar"]

# append(): adiciona ao final
tarefas.append("dormir")
print(tarefas)          # ['estudar', 'trabalhar', 'dormir']

# insert(): insere em posição específica
tarefas.insert(1, "comer")
print(tarefas)          # ['estudar', 'comer', 'trabalhar', 'dormir']

# extend(): adiciona múltiplos elementos de um iterável
mais_tarefas = ["ler", "exercitar"]
tarefas.extend(mais_tarefas)
print(tarefas)          # ['estudar', 'comer', 'trabalhar', 'dormir', 'ler', 'exercitar']

# Diferença entre extend() e operador +
# extend() modifica a lista original
a = [1, 2, 3]
b = [4, 5, 6]
a.extend(b)
print(a)                # [1, 2, 3, 4, 5, 6]

# O operador + cria uma nova lista
a = [1, 2, 3]
b = [4, 5, 6]
c = a + b
print(c)                # [1, 2, 3, 4, 5, 6]
print(a)                # [1, 2, 3] (original não modificado)

6. Removendo elementos

Para remover elementos, temos várias opções:

numeros = [10, 20, 30, 20, 40, 50]

# remove(): remove por valor (primeira ocorrência)
numeros.remove(20)
print(numeros)          # [10, 30, 20, 40, 50]

# pop(): remove por índice e retorna o valor
ultimo = numeros.pop()
print(ultimo)           # 50
print(numeros)          # [10, 30, 20, 40]

segundo = numeros.pop(1)
print(segundo)          # 30
print(numeros)          # [10, 20, 40]

# del: deleta por índice ou fatia
del numeros[0]
print(numeros)          # [20, 40]

# clear(): esvazia toda a lista
numeros.clear()
print(numeros)          # []

7. Operações úteis e boas práticas

Algumas operações essenciais para trabalhar com listas:

# Verificando existência com in e not in
frutas = ["maçã", "banana", "laranja"]
print("banana" in frutas)       # True
print("uva" not in frutas)      # True

# Tamanho da lista com len()
print(len(frutas))              # 3

# Copiando listas corretamente
original = [1, 2, 3]

# Método 1: copy()
copia1 = original.copy()

# Método 2: fatiamento [:]
copia2 = original[:]

# Método 3: list()
copia3 = list(original)

# Testando independência
copia1[0] = 999
print(original)                 # [1, 2, 3] (não foi alterada)
print(copia1)                   # [999, 2, 3]

# Cuidado com cópia rasa em listas aninhadas
aninhada = [[1, 2], [3, 4]]
copia_rasa = aninhada.copy()

copia_rasa[0][0] = 999
print(aninhada)                 # [[999, 2], [3, 4]] (foi alterada!)

# Para cópia profunda, use copy.deepcopy()
import copy
aninhada = [[1, 2], [3, 4]]
copia_profunda = copy.deepcopy(aninhada)

copia_profunda[0][0] = 999
print(aninhada)                 # [[1, 2], [3, 4]] (não foi alterada)

Boas práticas:
- Use listas quando precisar de coleções ordenadas e mutáveis
- Prefira tuplas para dados que não devem ser alterados
- Sempre faça cópias explícitas ao modificar listas em funções
- Verifique o tamanho antes de acessar por índice
- Use enumerate() para iterar com índice e valor
- Prefira list comprehensions para criar listas transformadas

As listas são ferramentas poderosas e flexíveis em Python. Dominar sua criação, acesso e modificação é essencial para qualquer programador Python, desde scripts simples até aplicações complexas.

Referências