Pular para o conteúdo
Editor

Listas e dicionários aninhados em Python: guia prático

Intermediário25 min6 exercícios85 XP

Este tutorial foi traduzido do original em inglês.Read in EnglishLeer en españolЧитать на русскомอ่านภาษาไทยAvisar sobre um erro de tradução

0/6 exercícios

Pense em uma escola. Uma escola tem salas de aula. Cada sala tem alunos. Cada aluno tem um nome, uma idade e uma lista de notas. São dados dentro de dados dentro de dados: dados aninhados.

Dados aninhados estão em toda parte na programação de verdade. Uma rede social guarda usuários que têm posts, e cada post tem comentários. Um jogo guarda fases que contêm inimigos, e cada inimigo tem seus atributos. Uma loja on-line tem categorias com produtos, e os produtos têm avaliações.

Neste tutorial, você vai aprender a montar, acessar, modificar e percorrer listas e dicionários aninhados. Essas habilidades são essenciais para trabalhar com dados do mundo real, principalmente com JSON vindo de APIs da web.

Como funcionam listas dentro de listas?

Uma lista pode ter outras listas como itens. Isso cria uma estrutura bidimensional, como uma grade ou uma tabela. Pense em uma planilha: linhas e colunas.

Uma lista aninhada que representa uma grade
# A 3x3 grid (like a tic-tac-toe board)
board = [
['X', 'O', 'X'],
['O', 'X', 'O'],
['X', ' ', 'O'],
]
for row in board:
print(row)
Saída
['X', 'O', 'X']
['O', 'X', 'O']
['X', ' ', 'O']

Para acessar um item de uma lista aninhada, você usa dois pares de colchetes. O primeiro escolhe a linha. O segundo escolhe a coluna.

Acessando itens com indexação dupla
board = [
['X', 'O', 'X'],
['O', 'X', 'O'],
['X', ' ', 'O'],
]
# board[row][column]
print(board[0][0]) # X (top-left)
print(board[1][1]) # X (center)
print(board[2][1]) # (space) (bottom-middle)
Saída
X
X

Você também pode modificar itens com a mesma sintaxe de colchetes duplos. É assim que você marcaria uma jogada em um jogo da velha.

Modificando itens em uma lista aninhada
board = [
[' ', ' ', ' '],
[' ', ' ', ' '],
[' ', ' ', ' '],
]
# Place some moves
board[0][0] = 'X' # top-left
board[1][1] = 'O' # center
board[0][2] = 'X' # top-right
for row in board:
print(row)
Saída
['X', ' ', 'X']
[' ', 'O', ' ']
[' ', ' ', ' ']

Como funcionam dicionários aninhados?

O valor de um dicionário pode ser outro dicionário. Isso cria uma estrutura em forma de árvore, em que você desce pelas chaves até chegar ao dado de que precisa.

Dicionários aninhados com acesso encadeado por chaves
school = {
'Room 101': {
'teacher': 'Ms. Smith',
'subject': 'Math',
'students': 28,
},
'Room 102': {
'teacher': 'Mr. Jones',
'subject': 'English',
'students': 25,
},
}
print(school['Room 101']['teacher']) # Ms. Smith
print(school['Room 102']['students']) # 25
Saída
Ms. Smith
25

Cada par de colchetes desce um nível. school['Room 101'] entrega o dicionário interno. Depois, ['teacher'] entrega o valor dentro desse dicionário interno.

Você também pode adicionar chaves novas ou atualizar valores em qualquer nível.

Modificando dicionários aninhados
school = {
'Room 101': {
'teacher': 'Ms. Smith',
'subject': 'Math',
},
}
# Update an existing value
school['Room 101']['subject'] = 'Algebra'
# Add a new key to the inner dict
school['Room 101']['students'] = 30
# Add an entirely new room
school['Room 103'] = {
'teacher': 'Ms. Lee',
'subject': 'Science',
'students': 22,
}
for room, info in school.items():
print(f"{room}: {info['teacher']} teaches {info['subject']}")
Saída
Room 101: Ms. Smith teaches Algebra
Room 103: Ms. Lee teaches Science

Listas de dicionários: o padrão mais comum

A estrutura aninhada mais comum na programação do dia a dia é a lista de dicionários. Cada dicionário representa um registro (um aluno, um produto, um usuário), e a lista reúne todos os registros.

Se você já viu dados vindos de uma API da web ou de um banco de dados, eles quase sempre têm a cara de uma lista de dicionários.

Uma lista de dicionários: registros de alunos
students = [
{'name': 'Alice', 'age': 15, 'grade': 92},
{'name': 'Bob', 'age': 16, 'grade': 85},
{'name': 'Charlie', 'age': 15, 'grade': 97},
]
# Access a specific student
print(students[0]['name']) # Alice
print(students[2]['grade']) # 97
# Loop through all students
for student in students:
print(f"{student['name']} is {student['age']} and scored {student['grade']}")
Saída
Alice
97
Alice is 15 and scored 92
Bob is 16 and scored 85
Charlie is 15 and scored 97

O padrão é sempre list[index][key]. O índice escolhe qual dicionário. A chave escolhe qual valor dentro desse dicionário.

Como acessar dados profundamente aninhados com segurança

Dados reais podem ter vários níveis de aninhamento. Uma empresa tem departamentos, cada departamento tem equipes, cada equipe tem membros. Acessar dados profundamente aninhados significa encadear vários colchetes.

Encadeando colchetes para acessar níveis profundos
company = {
'engineering': {
'backend': {
'members': ['Alice', 'Bob'],
'lead': 'Alice',
},
'frontend': {
'members': ['Charlie', 'Diana'],
'lead': 'Charlie',
},
},
}
# Get the backend team lead
print(company['engineering']['backend']['lead']) # Alice
# Get the second frontend team member
print(company['engineering']['frontend']['members'][1]) # Diana
Saída
Alice
Diana

O perigo do aninhamento profundo é que qualquer chave ausente causa um KeyError. Se os dados puderem estar incompletos, use o método .get(), que retorna None (ou um valor padrão) em vez de travar o programa.

Acesso seguro a dados aninhados com .get()
user = {
'name': 'Alice',
'profile': {
'bio': 'Python developer',
},
}
# Safe access with .get()
print(user.get('profile', {}).get('bio', 'No bio')) # Python developer
print(user.get('profile', {}).get('website', 'No site')) # No site
print(user.get('settings', {}).get('theme', 'default')) # default
Saída
Python developer
No site
default

Como percorrer estruturas de dados aninhadas

Quando você tem dados aninhados, muitas vezes precisa de laços aninhados. O laço externo passa pelos itens do nível de cima, e o laço interno passa pelos itens dentro de cada um deles. Às vezes uma função faz o trabalho interno por você: no primeiro exemplo abaixo, sum() e len() cuidam de cada lista interna, então um único laço é suficiente.

Percorrendo um dicionário de listas
# Each subject with its list of grades
classes = {
'Math': [85, 92, 78, 95],
'English': [88, 76, 91],
'Science': [93, 87, 82, 79, 95],
}
for subject, grades in classes.items():
average = sum(grades) / len(grades)
print(f"{subject}: average = {average:.1f}")
Saída
Math: average = 87.5
English: average = 85.0
Science: average = 87.2
Percorrendo uma grade 2D com enumerate
# Nested list: a grid of numbers
grid = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]
# Print each number with its position
for row_index, row in enumerate(grid):
for col_index, value in enumerate(row):
print(f"grid[{row_index}][{col_index}] = {value}")
Saída
grid[0][0] = 1
grid[0][1] = 2
grid[0][2] = 3
grid[1][0] = 4
grid[1][1] = 5
grid[1][2] = 6
grid[2][0] = 7
grid[2][1] = 8
grid[2][2] = 9

Em listas de dicionários, um único laço costuma ser suficiente, porque cada dicionário é um registro completo.

Filtrando uma lista de dicionários com verificações em listas aninhadas
products = [
{'name': 'Laptop', 'price': 999, 'tags': ['electronics', 'computers']},
{'name': 'Book', 'price': 15, 'tags': ['education', 'reading']},
{'name': 'Phone', 'price': 699, 'tags': ['electronics', 'mobile']},
]
# Find all electronics
for product in products:
if 'electronics' in product['tags']:
print(f"{product['name']}: ${product['price']}")
Saída
Laptop: $999
Phone: $699

Como montar estruturas de dados aninhadas do zero

Nem sempre você recebe dados aninhados prontos: às vezes precisa montá-los você mesmo. Um padrão comum é começar com uma estrutura vazia e adicionar itens dentro de um laço.

Montando um dicionário de listas por agrupamento
# Build a dictionary that groups words by their first letter
words = ['apple', 'avocado', 'banana', 'blueberry', 'cherry', 'coconut']
by_letter = {}
for word in words:
first = word[0]
if first not in by_letter:
by_letter[first] = []
by_letter[first].append(word)
for letter, group in by_letter.items():
print(f"{letter}: {group}")
Saída
a: ['apple', 'avocado']
b: ['banana', 'blueberry']
c: ['cherry', 'coconut']

Outra tarefa comum é transformar dados planos em estruturas aninhadas. Por exemplo, transformar listas separadas de nomes, idades e notas em uma lista de dicionários.

Combinando listas paralelas em uma lista de dicionários
# Transform parallel lists into a list of dicts
names = ['Alice', 'Bob', 'Charlie']
ages = [15, 16, 15]
grades = [92, 85, 97]
students = []
for i in range(len(names)):
student = {
'name': names[i],
'age': ages[i],
'grade': grades[i],
}
students.append(student)
for s in students:
print(s)
Saída
{'name': 'Alice', 'age': 15, 'grade': 92}
{'name': 'Bob', 'age': 16, 'grade': 85}
{'name': 'Charlie', 'age': 15, 'grade': 97}

Exercícios práticos

Acesse itens de uma lista aninhada
Escreva o código

Você tem uma grade de números 3x3. Exiba o valor do centro (linha 1, coluna 1) e depois o valor do canto inferior direito (linha 2, coluna 2). Cada um em uma linha separada.

grid = [
[10, 20, 30],
[40, 50, 60],
[70, 80, 90],
]
# Print the center value
# Print the bottom-right value
Preveja a saída: acesso a dicionários aninhados
Preveja a saída

Leia o código com atenção. O que ele vai exibir? Digite a saída exata.

data = {
'user': {
'name': 'Alice',
'scores': [80, 90, 100],
},
}
print(data['user']['name'])
print(data['user']['scores'][2])
Encontre a maior nota
Escreva o código

Percorra a lista de alunos e encontre o que tem a maior nota. Exiba o nome e a nota dele no formato: Best: Name (Grade)

students = [
{'name': 'Alice', 'grade': 88},
{'name': 'Bob', 'grade': 95},
{'name': 'Charlie', 'grade': 72},
{'name': 'Diana', 'grade': 91},
]
# Find and print the highest scorer
Agrupe palavras pela primeira letra
Escreva o código

Agrupe as palavras em um dicionário de acordo com a primeira letra. Depois, exiba cada grupo em uma linha separada no formato: letter: [words]

Exiba as letras em ordem alfabética.

words = ['ant', 'bear', 'apple', 'bat', 'cat', 'cow']
# Group by first letter and print
Corrija o bug: a armadilha da lista aninhada
Corrija o erro

Este código tenta criar uma grade 3x3 e marcar só a célula do centro com "X". Mas algo está errado: execute e veja! Corrija o bug para que só a célula do centro seja "X" e todas as outras continuem como ".".

Exiba cada linha da grade em uma linha separada.

row = ['.'] * 3
grid = [row] * 3
grid[1][1] = 'X'
for r in grid:
print(r)
Calcule a média de cada turma
Escreva o código

Você tem um dicionário em que cada chave é o nome de uma turma e cada valor é uma lista de dicionários de alunos. Calcule a nota média de cada turma e exiba no formato: ClassName: average

Arredonde cada média para 1 casa decimal. Exiba as turmas em ordem alfabética.

classes = {
'Math': [
{'name': 'Alice', 'grade': 90},
{'name': 'Bob', 'grade': 80},
],
'English': [
{'name': 'Charlie', 'grade': 85},
{'name': 'Diana', 'grade': 95},
{'name': 'Eve', 'grade': 78},
],
}
# Calculate and print each class average

Tutoriais relacionados

Este tutorial foi útil?