CSharp
Tutorial CSharp: Diccionarios
Aprende a usar diccionarios en C# para añadir, buscar, eliminar y recorrer datos con eficiencia y seguridad en tus aplicaciones.
Aprende CSharp y certifícateDictionary<TKey,TValue>
Los diccionarios son estructuras de datos fundamentales en C# que permiten almacenar información en forma de pares clave-valor. A diferencia de los arrays o listas que utilizan índices numéricos para acceder a los elementos, los diccionarios utilizan claves que pueden ser de casi cualquier tipo para acceder a sus valores correspondientes.
En C#, la clase Dictionary<TKey,TValue>
implementa esta estructura de datos, donde:
- TKey: representa el tipo de datos de la clave
- TValue: representa el tipo de datos del valor asociado
La principal ventaja de los diccionarios es la búsqueda eficiente. Mientras que buscar un elemento en una lista puede requerir recorrerla completamente (operación O(n)), los diccionarios permiten acceder directamente a un valor conociendo su clave (operación O(1) en promedio).
Creación de un diccionario
Para crear un diccionario en C#, necesitamos especificar los tipos de datos tanto para las claves como para los valores:
// Diccionario con claves de tipo string y valores de tipo int
Dictionary<string, int> edades = new Dictionary<string, int>();
// Diccionario con inicialización de valores
Dictionary<string, string> capitales = new Dictionary<string, string>()
{
{ "España", "Madrid" },
{ "Francia", "París" },
{ "Italia", "Roma" }
};
// Sintaxis alternativa de inicialización (C# 6.0+)
Dictionary<string, string> paises = new Dictionary<string, string>()
{
["ES"] = "España",
["FR"] = "Francia",
["IT"] = "Italia"
};
Características principales
Los diccionarios en C# tienen varias características importantes:
- Claves únicas: Cada clave solo puede aparecer una vez en el diccionario
- Acceso rápido: El tiempo de búsqueda es constante en promedio
- Claves tipadas: Tanto las claves como los valores deben ser del tipo declarado
- Colección dinámica: Puede crecer o reducirse según sea necesario
Restricciones de las claves
No cualquier tipo puede usarse como clave en un diccionario. Para ser una clave válida, un tipo debe:
- Implementar correctamente el método
GetHashCode()
para distribuir las claves uniformemente - Implementar correctamente el método
Equals()
para comparar claves - Ser inmutable (no cambiar después de ser añadido al diccionario)
Los tipos comunes que cumplen estos requisitos incluyen:
// Tipos primitivos
Dictionary<int, string> empleadosPorId = new Dictionary<int, string>();
Dictionary<string, double> preciosPorProducto = new Dictionary<string, double>();
// Tipos de valor personalizados (structs)
Dictionary<DateTime, string> eventosPorFecha = new Dictionary<DateTime, string>();
// Tipos de referencia que implementan correctamente Equals y GetHashCode
Dictionary<Guid, Usuario> usuariosPorGuid = new Dictionary<Guid, Usuario>();
Propiedades útiles
Los diccionarios proporcionan varias propiedades que facilitan su uso:
Dictionary<string, int> inventario = new Dictionary<string, int>()
{
{ "Manzanas", 25 },
{ "Naranjas", 32 },
{ "Plátanos", 15 }
};
// Obtener el número de elementos
int cantidad = inventario.Count; // 3
// Obtener colecciones de claves y valores
ICollection<string> productos = inventario.Keys;
ICollection<int> cantidades = inventario.Values;
Casos de uso comunes
Los diccionarios son especialmente útiles en situaciones como:
- Mapeo de identificadores a objetos: Cuando necesitas acceder rápidamente a objetos por un ID único
Dictionary<int, Cliente> clientesPorId = new Dictionary<int, Cliente>();
clientesPorId.Add(1001, new Cliente { Nombre = "Ana López", Email = "ana@ejemplo.com" });
// Acceso rápido sin necesidad de búsqueda lineal
Cliente cliente = clientesPorId[1001]; // O(1) en promedio
- Conteo de frecuencias: Para contar ocurrencias de elementos
string texto = "hola mundo hola";
Dictionary<string, int> frecuenciaPalabras = new Dictionary<string, int>();
foreach (string palabra in texto.Split(' '))
{
if (frecuenciaPalabras.ContainsKey(palabra))
frecuenciaPalabras[palabra]++;
else
frecuenciaPalabras[palabra] = 1;
}
// Resultado: { "hola": 2, "mundo": 1 }
- Caché de resultados: Para almacenar resultados de operaciones costosas
Dictionary<string, decimal> resultadosCache = new Dictionary<string, decimal>();
decimal CalcularResultado(string entrada)
{
// Si ya calculamos este valor antes, devolvemos el resultado almacenado
if (resultadosCache.ContainsKey(entrada))
return resultadosCache[entrada];
// Simulamos un cálculo costoso
decimal resultado = decimal.Parse(entrada) * 1.21m;
// Guardamos el resultado para futuras consultas
resultadosCache[entrada] = resultado;
return resultado;
}
Rendimiento
El rendimiento de los diccionarios es una de sus principales ventajas:
Operación | Complejidad promedio |
---|---|
Acceso | O(1) |
Inserción | O(1) |
Eliminación | O(1) |
Búsqueda | O(1) |
Esto contrasta con las listas, donde la búsqueda tiene una complejidad de O(n), lo que significa que el tiempo de búsqueda aumenta linealmente con el tamaño de la colección.
Consideraciones importantes
Al trabajar con diccionarios, es importante tener en cuenta:
- Las claves deben ser únicas. Intentar agregar una clave duplicada generará una excepción.
- Acceder a una clave inexistente con el operador
[]
lanzará unaKeyNotFoundException
. Es más seguro usar el métodoTryGetValue()
. - El orden de los elementos no está garantizado. Si necesitas un orden específico, considera usar
SortedDictionary<TKey,TValue>
oOrderedDictionary
. - Los diccionarios no son thread-safe por defecto. Para escenarios concurrentes, considera
ConcurrentDictionary<TKey,TValue>
.
Los diccionarios son una herramienta fundamental en el arsenal de cualquier programador de C#, permitiendo implementar soluciones eficientes para una amplia variedad de problemas de programación.
Añadir, buscar y eliminar
Trabajar con diccionarios en C# implica dominar las operaciones básicas de manipulación de datos: añadir elementos, buscar información y eliminar entradas. Estas operaciones son fundamentales para aprovechar la eficiencia que ofrecen los diccionarios en aplicaciones reales.
Añadir elementos a un diccionario
Existen varias formas de añadir elementos a un diccionario en C#:
- Método Add: La forma más explícita de agregar un nuevo par clave-valor.
Dictionary<string, int> puntuaciones = new Dictionary<string, int>();
// Añadir elementos con el método Add
puntuaciones.Add("Juan", 85);
puntuaciones.Add("María", 92);
- Operador de indexación: Permite tanto añadir como actualizar valores.
// Añadir elementos con el operador de indexación
puntuaciones["Pedro"] = 78;
Es importante tener en cuenta que el método Add
lanzará una excepción si intentamos añadir una clave que ya existe, mientras que el operador de indexación simplemente sobrescribirá el valor existente:
// Esto lanzará una System.ArgumentException
// puntuaciones.Add("Juan", 90);
// Esto actualizará el valor sin error
puntuaciones["Juan"] = 90;
- TryAdd: Disponible desde .NET Core 2.0, permite añadir un elemento solo si la clave no existe.
// Devuelve true si se añadió, false si la clave ya existía
bool fueAgregado = puntuaciones.TryAdd("Ana", 88);
Buscar elementos en un diccionario
La búsqueda es donde los diccionarios realmente destacan por su eficiencia. Hay varias formas de buscar información:
- Operador de indexación: Acceso directo por clave.
// Acceder a un valor conociendo su clave
int puntuacionJuan = puntuaciones["Juan"]; // 90
Sin embargo, este método lanzará una KeyNotFoundException
si la clave no existe, lo que puede causar errores en tiempo de ejecución.
- Método TryGetValue: La forma más segura de buscar valores.
// Forma segura de obtener un valor
if (puntuaciones.TryGetValue("Luis", out int puntuacionLuis))
{
Console.WriteLine($"Puntuación de Luis: {puntuacionLuis}");
}
else
{
Console.WriteLine("Luis no tiene puntuación registrada");
}
- Método ContainsKey: Verifica si una clave existe antes de intentar acceder a ella.
// Verificar si una clave existe
if (puntuaciones.ContainsKey("María"))
{
int puntuacion = puntuaciones["María"];
Console.WriteLine($"Puntuación de María: {puntuacion}");
}
- Método ContainsValue: Comprueba si un valor específico existe en el diccionario.
// Verificar si existe un valor específico
bool hayAlguienConPuntuacionPerfecta = puntuaciones.ContainsValue(100);
Es importante notar que ContainsValue
es menos eficiente que ContainsKey
, ya que requiere revisar todos los valores del diccionario (operación O(n)).
Eliminar elementos de un diccionario
Para eliminar elementos de un diccionario, disponemos de varias opciones:
- Método Remove: Elimina un elemento por su clave.
// Eliminar un elemento por su clave
bool fueEliminado = puntuaciones.Remove("Pedro");
El método Remove
devuelve true
si el elemento fue eliminado correctamente, o false
si la clave no existía.
- Método Remove con valor de salida: Desde .NET Core 2.0, podemos obtener el valor eliminado.
// Eliminar y obtener el valor eliminado
if (puntuaciones.Remove("María", out int puntuacionEliminada))
{
Console.WriteLine($"Se eliminó la puntuación de María: {puntuacionEliminada}");
}
- Método Clear: Elimina todos los elementos del diccionario.
// Eliminar todos los elementos
puntuaciones.Clear();
Patrones comunes de uso
Veamos algunos patrones comunes al trabajar con las operaciones básicas de diccionarios:
- Actualización condicional: Incrementar un contador solo si la clave existe.
Dictionary<string, int> contadorVisitas = new Dictionary<string, int>();
void RegistrarVisita(string pagina)
{
if (contadorVisitas.ContainsKey(pagina))
contadorVisitas[pagina]++;
else
contadorVisitas[pagina] = 1;
}
- Patrón de acceso seguro: Obtener un valor con un valor predeterminado si la clave no existe.
int ObtenerPuntuacion(string nombre)
{
return puntuaciones.TryGetValue(nombre, out int puntuacion)
? puntuacion
: 0; // Valor predeterminado
}
- Añadir o actualizar (upsert): Patrón común para mantener contadores o acumuladores.
Dictionary<string, int> inventario = new Dictionary<string, int>();
void AgregarProducto(string producto, int cantidad)
{
if (inventario.TryGetValue(producto, out int cantidadActual))
inventario[producto] = cantidadActual + cantidad;
else
inventario[producto] = cantidad;
}
Este patrón se puede simplificar en versiones más recientes de C# usando el operador de coalescencia nula:
void AgregarProducto(string producto, int cantidad)
{
inventario[producto] = (inventario.TryGetValue(producto, out int cantidadActual)
? cantidadActual
: 0) + cantidad;
}
Manejo de excepciones
Al trabajar con diccionarios, es importante manejar adecuadamente las posibles excepciones:
Dictionary<int, string> empleados = new Dictionary<int, string>();
empleados.Add(101, "Ana Martínez");
try
{
// Podría lanzar KeyNotFoundException
string nombre = empleados[102];
}
catch (KeyNotFoundException)
{
Console.WriteLine("No se encontró el empleado con ID 102");
}
try
{
// Podría lanzar ArgumentException
empleados.Add(101, "Ana López"); // Clave duplicada
}
catch (ArgumentException)
{
Console.WriteLine("Ya existe un empleado con ID 101");
}
Sin embargo, es mejor evitar estas excepciones usando los métodos seguros como TryGetValue
y TryAdd
cuando sea posible.
Rendimiento y consideraciones prácticas
- Capacidad inicial: Si conocemos aproximadamente cuántos elementos tendrá nuestro diccionario, podemos mejorar el rendimiento especificando una capacidad inicial.
// Crear un diccionario con capacidad inicial para 1000 elementos
Dictionary<string, Cliente> clientes = new Dictionary<string, Cliente>(1000);
- Eliminar durante la iteración: No podemos eliminar elementos mientras iteramos un diccionario. Una solución es recopilar las claves a eliminar primero:
Dictionary<string, int> datos = new Dictionary<string, int>
{
{ "A", 1 }, { "B", 2 }, { "C", 3 }, { "D", 4 }
};
// Recopilar claves a eliminar
List<string> clavesAEliminar = new List<string>();
foreach (var par in datos)
{
if (par.Value % 2 == 0) // Eliminar valores pares
clavesAEliminar.Add(par.Key);
}
// Eliminar después de la iteración
foreach (string clave in clavesAEliminar)
{
datos.Remove(clave);
}
- Verificación de existencia y acceso: Evita verificar la existencia y luego acceder, ya que implica dos búsquedas. Usa
TryGetValue
en su lugar:
// Evitar esto (dos búsquedas)
if (diccionario.ContainsKey(clave))
{
var valor = diccionario[clave];
// Usar valor...
}
// Preferir esto (una sola búsqueda)
if (diccionario.TryGetValue(clave, out var valor))
{
// Usar valor...
}
Dominar estas operaciones básicas de añadir, buscar y eliminar elementos te permitirá aprovechar al máximo la eficiencia y flexibilidad que ofrecen los diccionarios en C#, facilitando la implementación de soluciones elegantes para una amplia variedad de problemas de programación.
Recorrido de diccionarios
Los diccionarios en C# no solo son útiles para almacenar y recuperar datos mediante claves, sino que también ofrecen diversas formas de recorrer su contenido. Esto es fundamental cuando necesitamos procesar todos los elementos o buscar información basada en criterios más complejos que una simple clave.
Iteración básica con foreach
La forma más común de recorrer un diccionario es mediante un bucle foreach
, que nos permite acceder a cada par clave-valor:
Dictionary<string, int> inventario = new Dictionary<string, int>()
{
{ "Manzanas", 150 },
{ "Naranjas", 75 },
{ "Plátanos", 120 }
};
// Recorrer todos los pares clave-valor
foreach (KeyValuePair<string, int> item in inventario)
{
Console.WriteLine($"Producto: {item.Key}, Cantidad: {item.Value}");
}
En este ejemplo, cada iteración nos proporciona un objeto KeyValuePair<TKey, TValue>
que contiene tanto la clave como el valor de cada elemento.
Uso de var para simplificar la sintaxis
Podemos simplificar el código anterior utilizando la inferencia de tipos con var
:
// Sintaxis más concisa con var
foreach (var item in inventario)
{
Console.WriteLine($"Producto: {item.Key}, Cantidad: {item.Value}");
}
Deconstrucción de pares clave-valor (C# 7.0+)
En versiones más recientes de C#, podemos utilizar la deconstrucción para extraer directamente la clave y el valor:
// Deconstrucción de KeyValuePair
foreach (var (producto, cantidad) in inventario)
{
Console.WriteLine($"Producto: {producto}, Cantidad: {cantidad}");
}
Esta sintaxis hace que el código sea más legible y directo, especialmente cuando trabajamos con nombres de variables significativos.
Recorrido solo de claves
Si solo necesitamos trabajar con las claves del diccionario, podemos iterar sobre la colección Keys
:
// Recorrer solo las claves
foreach (string producto in inventario.Keys)
{
Console.WriteLine($"Producto en inventario: {producto}");
}
Este enfoque es útil cuando solo necesitamos conocer qué elementos están en el diccionario, sin importar sus valores asociados.
Recorrido solo de valores
De manera similar, podemos recorrer únicamente los valores utilizando la colección Values
:
// Recorrer solo los valores
foreach (int cantidad in inventario.Values)
{
Console.WriteLine($"Cantidad en stock: {cantidad}");
}
// Calcular el total de productos
int totalProductos = 0;
foreach (int cantidad in inventario.Values)
{
totalProductos += cantidad;
}
Console.WriteLine($"Total de productos: {totalProductos}");
Este método es especialmente útil para realizar cálculos o estadísticas sobre los valores almacenados.
Conversión a otras colecciones
A veces, puede ser útil convertir un diccionario a otra estructura de datos para facilitar su procesamiento:
// Convertir a lista de pares clave-valor
List<KeyValuePair<string, int>> listaInventario = inventario.ToList();
// Convertir a arrays separados
string[] productos = inventario.Keys.ToArray();
int[] cantidades = inventario.Values.ToArray();
Estas conversiones son útiles cuando necesitamos pasar los datos a métodos que esperan otros tipos de colecciones o cuando queremos aplicar operaciones específicas de listas o arrays.
Ordenamiento durante el recorrido
Los diccionarios no mantienen un orden específico, pero podemos ordenar los elementos durante el recorrido:
// Recorrer ordenado por clave (orden alfabético de productos)
foreach (var item in inventario.OrderBy(x => x.Key))
{
Console.WriteLine($"Producto: {item.Key}, Cantidad: {item.Value}");
}
// Recorrer ordenado por valor (de menor a mayor cantidad)
foreach (var item in inventario.OrderBy(x => x.Value))
{
Console.WriteLine($"Producto: {item.Key}, Cantidad: {item.Value}");
}
// Recorrer ordenado por valor (de mayor a menor cantidad)
foreach (var item in inventario.OrderByDescending(x => x.Value))
{
Console.WriteLine($"Producto: {item.Key}, Cantidad: {item.Value}");
}
Estos ejemplos utilizan LINQ para ordenar los elementos durante la iteración, sin modificar el diccionario original.
Filtrado durante el recorrido
También podemos usar LINQ para filtrar elementos mientras recorremos el diccionario:
// Filtrar productos con más de 100 unidades
var productosAbundantes = inventario.Where(x => x.Value > 100);
foreach (var item in productosAbundantes)
{
Console.WriteLine($"Producto abundante: {item.Key} ({item.Value} unidades)");
}
Esta técnica es muy útil para encontrar elementos que cumplan ciertos criterios sin tener que escribir condiciones dentro del bucle foreach.
Recorrido con índice
A diferencia de las listas, los diccionarios no tienen un índice numérico natural. Sin embargo, si necesitamos un índice durante la iteración, podemos crearlo:
// Recorrer con un índice manual
int indice = 0;
foreach (var item in inventario)
{
Console.WriteLine($"Ítem #{indice}: {item.Key} = {item.Value}");
indice++;
}
// Alternativa con Select y LINQ
var itemsConIndice = inventario.Select((item, index) => new { Index = index, Key = item.Key, Value = item.Value });
foreach (var item in itemsConIndice)
{
Console.WriteLine($"Ítem #{item.Index}: {item.Key} = {item.Value}");
}
Recorrido seguro durante modificaciones
Es importante recordar que no podemos modificar un diccionario mientras lo estamos recorriendo con foreach. Si necesitamos hacer esto, debemos tomar un enfoque diferente:
// Crear una copia de las claves para iterar de forma segura
foreach (string producto in new List<string>(inventario.Keys))
{
if (inventario[producto] == 0)
{
inventario.Remove(producto);
Console.WriteLine($"Producto agotado eliminado: {producto}");
}
}
En este ejemplo, creamos una copia de las claves para iterar sobre ella, lo que nos permite modificar el diccionario original de forma segura.
Ejemplo práctico: Análisis de texto
Veamos un ejemplo práctico de cómo recorrer un diccionario para analizar la frecuencia de palabras en un texto:
string texto = "El perro persigue al gato y el gato corre rápido porque el perro ladra fuerte";
Dictionary<string, int> frecuenciaPalabras = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
// Contar frecuencia de palabras
foreach (string palabra in texto.Split(' '))
{
if (frecuenciaPalabras.ContainsKey(palabra))
frecuenciaPalabras[palabra]++;
else
frecuenciaPalabras[palabra] = 1;
}
// Mostrar resultados ordenados por frecuencia
Console.WriteLine("Análisis de frecuencia de palabras:");
foreach (var item in frecuenciaPalabras.OrderByDescending(x => x.Value))
{
Console.WriteLine($"'{item.Key}': aparece {item.Value} {(item.Value == 1 ? "vez" : "veces")}");
}
Este ejemplo muestra cómo podemos combinar la creación de un diccionario, su recorrido y el uso de LINQ para ordenar los resultados, creando una solución elegante para un problema común.
Rendimiento en recorridos
Al recorrer diccionarios grandes, es importante considerar el rendimiento:
- El recorrido con
foreach
tiene una complejidad de O(n), donde n es el número de elementos - Recorrer solo
Keys
oValues
tiene el mismo rendimiento que recorrer todo el diccionario - Las operaciones de ordenamiento con LINQ (
OrderBy
, etc.) tienen un costo adicional de O(n log n) - La conversión a otras colecciones (
ToList
,ToArray
) requiere memoria adicional
Para diccionarios pequeños, estas consideraciones no son críticas, pero pueden ser importantes cuando trabajamos con grandes volúmenes de datos.
El dominio de las diferentes técnicas de recorrido de diccionarios te permitirá procesar datos de manera eficiente y elegante, aprovechando al máximo esta versátil estructura de datos en tus aplicaciones C#.
Otras lecciones de CSharp
Accede a todas las lecciones de CSharp y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.
Introducción A C#
Introducción Y Entorno
Creación De Proyecto C#
Introducción Y Entorno
Variables Y Constantes
Sintaxis
Tipos De Datos
Sintaxis
Operadores
Sintaxis
Control De Flujo
Sintaxis
Funciones
Sintaxis
Estructuras De Control Iterativo
Sintaxis
Interpolación De Strings
Sintaxis
Estructuras De Control Condicional
Sintaxis
Manejo De Valores Nulos
Sintaxis
Clases Y Encapsulación
Programación Orientada A Objetos
Objetos
Programación Orientada A Objetos
Constructores Y Destructores
Programación Orientada A Objetos
Herencia
Programación Orientada A Objetos
Polimorfismo
Programación Orientada A Objetos
Genéricos
Programación Orientada A Objetos
Métodos Virtuales Y Sobrecarga
Programación Orientada A Objetos
Clases Abstractas
Programación Orientada A Objetos
Interfaces
Programación Orientada A Objetos
Propiedades Y Encapsulación
Programación Orientada A Objetos
Métodos De Extensión
Programación Orientada A Objetos
Clases Y Objetos
Programación Orientada A Objetos
Clases Parciales
Programación Orientada A Objetos
Miembros Estáticos
Programación Orientada A Objetos
Tuplas Y Tipos Anónimos
Programación Orientada A Objetos
Arrays Y Listas
Colecciones Y Linq
Diccionarios
Colecciones Y Linq
Conjuntos, Colas Y Pilas
Colecciones Y Linq
Uso De Consultas Linq
Colecciones Y Linq
Linq Avanzado
Colecciones Y Linq
Colas Y Pilas
Colecciones Y Linq
Conjuntos
Colecciones Y Linq
Linq Básico
Colecciones Y Linq
Delegados Funcionales
Programación Funcional
Records
Programación Funcional
Expresiones Lambda
Programación Funcional
Linq Funcional
Programación Funcional
Fundamentos De La Programación Funcional
Programación Funcional
Pattern Matching
Programación Funcional
Testing Unitario Con Xunit
Testing
Excepciones
Excepciones
Delegados
Programación Asíncrona
Eventos
Programación Asíncrona
Lambdas
Programación Asíncrona
Uso De Async Y Await
Programación Asíncrona
Tareas
Programación Asíncrona
Ejercicios de programación de CSharp
Evalúa tus conocimientos de esta lección Diccionarios con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.
CRUD en C# de modelo Customer sobre una lista
Arrays y listas
Objetos
Excepciones
Eventos
Lambdas
Diccionarios en C#
Variables y constantes
Tipos de datos
Herencia
Operadores
Uso de consultas LINQ
Clases y encapsulación
Uso de consultas LINQ
Excepciones
Control de flujo
Eventos
Diccionarios
Tipos de datos
Conjuntos, colas y pilas
Lambdas
Conjuntos, colas y pilas
Uso de async y await
Tareas
Constructores y destructores
Operadores
Arrays y listas
Polimorfismo
Polimorfismo
Variables y constantes
Proyecto colecciones y LINQ en C#
Clases y encapsulación
Creación de proyecto C#
Uso de async y await
Funciones
Delegados
Delegados
Constructores y destructores
Objetos
Control de flujo
Funciones
Tareas
Proyecto sintaxis en C#
Herencia C Sharp
OOP en C Sharp
Diccionarios
Introducción a C#
En esta lección
Objetivos de aprendizaje de esta lección
- Comprender la estructura y características de la clase Dictionary<TKey,TValue> en C#.
- Aprender a crear, añadir, buscar y eliminar elementos en un diccionario.
- Conocer las restricciones y requisitos para usar tipos como claves en diccionarios.
- Dominar las diferentes formas de recorrer un diccionario y procesar sus elementos.
- Identificar buenas prácticas y consideraciones de rendimiento al trabajar con diccionarios.