¿Qué es una NamedTuple?

 Te explico NamedTuple con una analogía de fichas de biblioteca:

📚 Analogía de la Biblioteca

Imagina que en una biblioteca tienes dos tipos de fichas para los libros:

1. Tupla Normal = Ficha básica sin etiquetas

python
# Como una ficha que solo dice: "Python, Guido, 300"
libro = ("Python", "Guido", 300)

Problema: ¿Qué significa cada número?

  • libro[0] → ¿Título? ¿Autor?

  • libro[2] → ¿Páginas? ¿Año?

2. NamedTuple = Ficha con campos etiquetados

python
from typing import NamedTuple

class Libro(NamedTuple):
    titulo: str
    autor: str
    paginas: int

# Ahora es claro y organizado
mi_libro = Libro("Python", "Guido", 300)

🎯 ¿Por qué usar NamedTuple?

Ventajas:

python
# Acceso claro por NOMBRE (no solo por posición)
print(mi_libro.titulo)    # "Python"  ✅
print(mi_libro.autor)     # "Guido"   ✅
print(mi_libro.paginas)   # 300       ✅

# Pero también puedes usar índices
print(mi_libro[0])        # "Python"  ✅

# Es inmutable (como las fichas de biblioteca reales)
# mi_libro.titulo = "Java"  # ❌ Error! No puedes modificar

🔧 Casos de uso perfectos

Coordenadas GPS:

python
class Coordenada(NamedTuple):
    latitud: float
    longitud: float
    altitud: float = 0.0  # Valor por defecto

casa = Coordenada(40.7128, -74.0060)
print(f"Estás en latitud {casa.latitud}")

Información de persona:

python
class Persona(NamedTuple):
    nombre: str
    edad: int
    email: str

usuario = Persona("Ana", 25, "ana@email.com")

⚡ vs Diccionarios vs Clases Normales

TipoInmutableMemoriaLegibilidad
Dict❌ Mutable+datos["titulo"]
Class❌ Mutable+++datos.titulo
NamedTuple✅ Inmutable+datos.titulo ✅

💡 Conclusión

NamedTuple es como tener lo mejor de ambos mundos:

  • La claridad de los objetos con atributos

  • La eficiencia e inmutabilidad de las tuplas

  • Perfecto para datos que no cambiarán

¿Te quedó claro? ¡Es como organizar tu biblioteca mental! 

¿Qué es una NamedTuple?

Una NamedTuple es una estructura de datos que combina las ventajas de las tuplas tradicionales con la capacidad de acceder a los elementos por nombre, no solo por índice.

Creación de una NamedTuple

Método 1: Usando namedtuple de collections

python
from collections import namedtuple

# Definir una NamedTuple
Persona = namedtuple('Persona', ['nombre', 'edad', 'ciudad'])

# Crear instancias
persona1 = Persona('Ana', 25, 'Madrid')
persona2 = Persona(nombre='Carlos', edad=30, ciudad='Barcelona')

print(persona1.nombre)  # Ana
print(persona1[0])      # Ana (acceso por índice)

Método 2: Sintaxis más moderna (Python 3.6+)

python
from typing import NamedTuple

class Persona(NamedTuple):
    nombre: str
    edad: int
    ciudad: str

persona = Persona('María', 28, 'Sevilla')
print(persona.nombre)  # María

Ventajas de las NamedTuple

1. Acceso por nombre y por índice

python
punto = namedtuple('Punto', ['x', 'y'])
p = punto(10, 20)

print(p.x)     # 10
print(p[0])    # 10
print(p.y)     # 20
print(p[1])    # 20

2. Inmutabilidad

python
p = punto(5, 10)
# p.x = 15  # ¡Error! Las NamedTuple son inmutables

3. Métodos útiles

python
p = punto(3, 4)

# Convertir a diccionario
print(p._asdict())  # {'x': 3, 'y': 4}

# Reemplazar valores (crea nueva instancia)
p2 = p._replace(x=7)
print(p2)  # punto(x=7, y=4)

# Obtener campos
print(p._fields)  # ('x', 'y')

4. Valores por defecto

python
Persona = namedtuple('Persona', ['nombre', 'edad', 'ciudad'])
PersonaConDefault = namedtuple('Persona', ['nombre', 'edad', 'ciudad'], defaults=['Desconocida', 0])

persona = PersonaConDefault('Juan')
print(persona)  # Persona(nombre='Juan', edad=0, ciudad='Desconocida')

Ejemplos prácticos

Ejemplo 1: Coordenadas

python
from collections import namedtuple

Coordenada = namedtuple('Coordenada', ['latitud', 'longitud'])

madrid = Coordenada(40.4168, -3.7038)
print(f"Latitud: {madrid.latitud}, Longitud: {madrid.longitud}")

Ejemplo 2: Productos

python
from typing import NamedTuple

class Producto(NamedTuple):
    nombre: str
    precio: float
    stock: int

producto = Producto('Laptop', 999.99, 5)
print(f"{producto.nombre}: ${producto.precio}")

Ejemplo 3: Desempaquetado

python
Persona = namedtuple('Persona', ['nombre', 'edad'])

def procesar_persona(persona):
    nombre, edad = persona  # Desempaquetado como tupla normal
    return f"{nombre} tiene {edad} años"

persona = Persona('Laura', 25)
print(procesar_persona(persona))  # Laura tiene 25 años

NamedTuple vs otras estructuras

CaracterísticaNamedTupleTupla normalDiccionarioClase normal
InmutableDepende
Acceso por nombre
Memoria eficiente
Métodos personalizadosLimitado

Cuándo usar NamedTuple

  • ✅ Cuando necesitas una estructura de datos inmutable

  • ✅ Cuando quieres acceso por nombre pero con eficiencia de memoria

  • ✅ Para representar registros o estructuras simples

  • ✅ Cuando la claridad del código es importante

Resumen

Las NamedTuple son perfectas para cuando necesitas:

  • La inmutabilidad de las tuplas

  • La legibilidad del acceso por nombre

  • Eficiencia de memoria

  • Estructuras de datos simples y predecibles


 Explicación con tupla_normal = ("Python", "Guido", 300)

Tupla Normal (problema)

python
tupla_normal = ("Python", "Guido", 300)

Problema: ¿Qué significa cada posición?

  • tupla_normal[0] → ¿"Python" es el título? ¿el lenguaje?

  • tupla_normal[1] → ¿"Guido" es el autor? ¿el editor?

  • tupla_normal[2] → ¿300 son páginas? ¿año? ¿precio?


Usando realmente tupla_normal

Opción 1: Desempaquetado directo

python
from typing import NamedTuple

tupla_normal = ("Python", "Guido", 300)

class Libro(NamedTuple):
    titulo: str
    autor: str
    paginas: int

# Usando los valores de tupla_normal directamente
mi_libro = Libro(tupla_normal[0], tupla_normal[1], tupla_normal[2])

Opción 2: Desempaquetado con asterisco

python
from typing import NamedTuple

tupla_normal = ("Python", "Guido", 300)

class Libro(NamedTuple):
    titulo: str
    autor: str
    paginas: int

# ¡Esto SÍ usa tupla_normal!
mi_libro = Libro(*tupla_normal)  # El * "expande" la tupla

🎯 ¿Qué hace *tupla_normal?

python
# Esto:
Libro(*tupla_normal)

# Es equivalente a:
Libro(tupla_normal[0], tupla_normal[1], tupla_normal[2])

# Que es equivalente a:
Libro("Python", "Guido", 300)

🔍 Verificación

python
print(tupla_normal)    # ("Python", "Guido", 300)
print(mi_libro)        # Libro(titulo='Python', autor='Guido', paginas=300)

# Ahora puedes usar nombres claros
print(f"Libro: {mi_libro.titulo} by {mi_libro.autor}, {mi_libro.paginas} páginas")

✅ Flujo completo correcto:

python
# 1. Tengo una tupla normal (datos crudos)
tupla_normal = ("Python", "Guido", 300)

# 2. Defino una estructura NamedTuple
class Libro(NamedTuple):
    titulo: str
    autor: str
    paginas: int

# 3. CONVIERTO mi tupla_normal en NamedTuple
mi_libro = Libro(*tupla_normal)  # ← ¡Aquí SÍ uso tupla_normal!

# 4. Ahora tengo acceso por nombre
print(mi_libro.autor)  # "Guido" ✅

¡Perdón por la confusión! Ahora sí estoy usando tupla_normal realmente. El truco está en el * que expande la tupla como argumentos.

Comentarios

Entradas populares de este blog

¿Qué es un Closure?

4 tipos de colecciones de datos más

Funciones en Python: con y sin paréntesis