Variables y tipos de datos: la guía definitiva para principiantes

D
DanisCh
(Actualizado: ) • 14 min de lectura
Variables y tipos de datos: la guía definitiva para principiantes
Consejos para estudiar programación Empezar desde cero

Cuando aprendes a programar, las variables y los tipos de datos son lo primero que aparece en prácticamente cualquier tutorial. Y con razón: son los ladrillos fundamentales de cualquier programa. Sin entenderlos bien, todo lo demás se tambalea. En esta guía vas a aprender qué son, cómo funcionan y cuáles son las diferencias entre los lenguajes más populares, con ejemplos que puedes ejecutar tú mismo.

Qué es una variable

Una variable es un nombre que le das a un espacio en la memoria del ordenador donde puedes guardar un valor. Piensa en ella como una caja con una etiqueta: la etiqueta es el nombre de la variable y lo que hay dentro es el valor.

# Python
edad = 25
nombre = "Ana"
precio = 19.99
// JavaScript
let edad = 25;
let nombre = "Ana";
let precio = 19.99;

En estos ejemplos, edad, nombre y precio son variables. El símbolo = no significa "igual" en el sentido matemático: significa "asignar". Le estás diciendo al programa "guarda el valor 25 en la caja llamada edad".

Lo que hace que las variables sean útiles es que puedes cambiar su contenido a lo largo del programa:

# Python
puntuacion = 0
print(puntuacion)   # 0

puntuacion = 10
print(puntuacion)   # 10

puntuacion = puntuacion + 5
print(puntuacion)   # 15

Reglas para nombrar variables

No puedes llamar a una variable de cualquier manera. Casi todos los lenguajes comparten estas reglas básicas:

  • El nombre puede contener letras, números y el guión bajo (_).
  • No puede empezar por un número.
  • No puede contener espacios (se usa el guión bajo en su lugar).
  • No puede ser una palabra reservada del lenguaje (if, for, while, class, etc.).
# Nombres válidos
nombre_usuario = "Ana"
edad2 = 25
_precio_total = 49.99
esPremium = True

# Nombres NO válidos (causarían error)
# 2nombre = "Ana"     → empieza por número
# nombre usuario = "" → tiene espacio
# if = 10            → 'if' es palabra reservada

Además de las reglas obligatorias, hay convenciones que la comunidad de cada lenguaje sigue por consistencia. Las más habituales son:

  • snake_case: palabras separadas por guiones bajos. Es la convención estándar en Python: nombre_usuario, precio_total.
  • camelCase: la primera palabra en minúscula y el resto empiezan en mayúscula. Estándar en JavaScript para variables y funciones: nombreUsuario, precioTotal.
  • PascalCase: todas las palabras empiezan en mayúscula. Se usa para nombres de clases en casi todos los lenguajes: NombreUsuario, PrecioTotal.

Qué son los tipos de datos

Cada valor que guardas en una variable tiene un tipo. El tipo determina qué clase de información es y qué operaciones puedes hacer con ella. No es lo mismo el número 5 que el texto "5": aunque se parezcan visualmente, el programa los trata de forma completamente diferente.

# Python: diferencia entre el número 5 y el texto "5"
numero = 5
texto  = "5"

print(numero + 3)    # 8  ← suma numérica
print(texto  + "3")  # "53" ← concatenación de texto

# Si intentas sumar número y texto:
# print(numero + texto)  → TypeError: operación no permitida entre int y str

Los tipos de datos más comunes

Números enteros (int)

Representan números sin parte decimal: positivos, negativos y el cero.

# Python
edad       = 25
temperatura = -5
año        = 2026
contador   = 0

# Operaciones con enteros
print(10 + 3)   # 13
print(10 - 3)   # 7
print(10 * 3)   # 30
print(10 // 3)  # 3  ← división entera (resultado sin decimales)
print(10 % 3)   # 1  ← módulo (el resto de la división)
print(2 ** 10)  # 1024 ← potencia

 

// JavaScript
let edad = 25;
let temperatura = -5;

console.log(10 + 3);   // 13
console.log(10 - 3);   // 7
console.log(10 * 3);   // 30
console.log(Math.floor(10 / 3));  // 3 ← división entera
console.log(10 % 3);   // 1
console.log(2 ** 10);  // 1024
// Java: los tipos son explícitos, hay que declararlos
int edad = 25;
int temperatura = -5;
long poblacion = 8_000_000_000L;  // long para números muy grandes

Números decimales (float / double)

Representan números con parte decimal. Se llaman "de punto flotante" porque el punto decimal puede moverse.

# Python
precio  = 19.99
altura  = 1.75
pi      = 3.14159

print(0.1 + 0.2)   # 0.30000000000000004
# ¡Atención! Los decimales no son exactos en la mayoría de lenguajes
# Es una limitación de cómo los ordenadores representan los números en binario
# Para dinero, usa siempre el tipo Decimal (Python) o una librería específica

from decimal import Decimal
precio = Decimal("19.99")
iva    = Decimal("0.21")
print(precio * (1 + iva))   # 24.1879  ← sin errores de precisión
// JavaScript: no distingue entre int y float, todo es 'number'
let precio = 19.99;
let entero = 5;       // también es number, aunque sea entero

console.log(0.1 + 0.2);   // 0.30000000000000004 (mismo problema)
console.log((0.1 + 0.2).toFixed(2));  // "0.30" ← formatear con 2 decimales

Texto (String)

Las cadenas de texto almacenan secuencias de caracteres: letras, números, símbolos, espacios. Se delimitan con comillas simples o dobles (dependiendo del lenguaje).

# Python: comillas simples o dobles, indistintamente
nombre   = "Ana García"
ciudad   = 'Madrid'
vacio    = ""
multilin = """Este texto
ocupa varias
líneas"""

# Operaciones con strings
print(len(nombre))           # 10 ← longitud
print(nombre.upper())        # "ANA GARCÍA"
print(nombre.lower())        # "ana garcía"
print(nombre.replace("Ana", "Carlos"))  # "Carlos García"
print(nombre[0])             # "A" ← primer carácter (índice 0)
print(nombre[4:9])           # "García" ← slicing (subcadena)

# Comprobar si contiene algo
print("Ana" in nombre)       # True
print(nombre.startswith("Ana"))  # True

# Interpolación (la forma más moderna de combinar texto y variables)
edad = 25
print(f"Me llamo {nombre} y tengo {edad} años")
# "Me llamo Ana García y tengo 25 años"

 

// JavaScript
let nombre = "Ana García";
let ciudad = 'Madrid';

console.log(nombre.length);              // 10
console.log(nombre.toUpperCase());       // "ANA GARCÍA"
console.log(nombre.includes("Ana"));    // true
console.log(nombre.replace("Ana", "Carlos"));  // "Carlos García"
console.log(nombre[0]);                  // "A"
console.log(nombre.slice(4, 10));        // "García"

// Template literals: la forma moderna de interpolar en JavaScript
let edad = 25;
console.log(`Me llamo ${nombre} y tengo ${edad} años`);

Booleanos (bool)

Solo pueden tener dos valores: verdadero o falso. Son fundamentales para el control del flujo de un programa: las condiciones y los bucles dependen de ellos.

# Python: True y False (con mayúscula)
activo       = True
tiene_cuenta = False
mayor_edad   = 18 >= 18   # True (el resultado de una comparación es un booleano)

# Operadores lógicos
print(True and True)    # True  (los dos deben ser True)
print(True and False)   # False
print(True or False)    # True  (al menos uno debe ser True)
print(not True)         # False (invierte el valor)

# Comparaciones que producen booleanos
edad = 20
print(edad >= 18)       # True
print(edad == 18)       # False (== compara igualdad, no confundir con = que asigna)
print(edad != 18)       # True (diferente)

# En Python, muchos valores se comportan como False:
# 0, "", [], {}, None → se evalúan como False
# Cualquier otro valor → se evalúa como True
if "":
    print("esto no se imprime")   # string vacío es "falsy"
if "hola":
    print("esto sí se imprime")   # string con contenido es "truthy"
// JavaScript: true y false (en minúscula)
let activo = true;
let tieneCuenta = false;

console.log(true && true);    // true
console.log(true && false);   // false
console.log(true || false);   // true
console.log(!true);           // false

// Valores "falsy" en JavaScript (similares a Python pero con alguna diferencia):
// 0, "", null, undefined, NaN, false → se evalúan como false
// Cuidado: "0" (string) es truthy en JavaScript

None / null / undefined

Representan la ausencia de valor. Cada lenguaje los llama de forma diferente y tienen matices distintos.

# Python: None (con N mayúscula)
resultado = None   # todavía no tenemos un valor

def buscar_usuario(id):
    # Si no encuentra el usuario, devuelve None
    if id not in base_de_datos:
        return None
    return base_de_datos[id]

usuario = buscar_usuario(999)
if usuario is None:   # en Python se compara con 'is None', no con '== None'
    print("Usuario no encontrado")
// JavaScript tiene null Y undefined (dos conceptos distintos):

let sinAsignar;              // undefined: declarada pero sin valor asignado
let sinValor = null;         // null: intencionalmente vacío

console.log(typeof sinAsignar);   // "undefined"
console.log(typeof sinValor);     // "object" (un bug histórico de JavaScript)

// Comprobar si algo es null o undefined de forma segura:
if (sinAsignar == null) { ... }    // == compara null y undefined igual (no recomendado)
if (sinAsignar === undefined) { }  // === compara tipo y valor (recomendado)
if (sinValor === null) { }

Tipado estático vs tipado dinámico

Una de las diferencias más importantes entre lenguajes es cómo manejan los tipos.

En los lenguajes de tipado dinámico (Python, JavaScript, Ruby), no necesitas declarar el tipo de una variable. El lenguaje lo deduce del valor que le asignas, y puedes cambiar el tipo en cualquier momento:

# Python: tipado dinámico
variable = 42       # ahora es int
variable = "hola"   # ahora es str (el lenguaje no protesta)
variable = [1, 2]   # ahora es list

# Puedes ver el tipo actual con type()
print(type(42))     # 
print(type("hola")) # 
print(type(True))   # 

En los lenguajes de tipado estático (Java, C#, TypeScript, Go), el tipo se declara explícitamente y no puede cambiar:

// Java: tipado estático estricto
int numero = 42;
// numero = "hola";   → error de compilación: tipos incompatibles

String nombre = "Ana";
// nombre = 100;      → error de compilación

// TypeScript: tipado estático sobre JavaScript
let numero: number = 42;
let nombre: string = "Ana";
let activo: boolean = true;

// numero = "hola";  → error: Type 'string' is not assignable to type 'number'

El tipado estático detecta muchos errores antes de ejecutar el programa. El tipado dinámico es más flexible y rápido de escribir, pero los errores de tipo aparecen en tiempo de ejecución.

Python tiene type hints desde la versión 3.5 que permiten añadir tipos opcionalmente, y herramientas como mypy que los verifican:

# Python con type hints (opcional pero recomendado en proyectos grandes)
def saludar(nombre: str, edad: int) -> str:
    return f"Hola {nombre}, tienes {edad} años"

# El lenguaje no obliga a respetar los tipos, pero mypy sí lo verificará
# mypy archivo.py → mostrará errores si se pasan tipos incorrectos

Colecciones: guardar múltiples valores

Hasta ahora hemos visto tipos que guardan un solo valor. Las colecciones permiten guardar varios valores en una sola variable.

Listas y arrays

# Python: listas (tamaño variable, pueden mezclar tipos aunque no es recomendable)
frutas = ["manzana", "banana", "naranja"]
numeros = [1, 2, 3, 4, 5]

print(frutas[0])     # "manzana" (índice 0 = primer elemento)
print(frutas[-1])    # "naranja" (índice -1 = último elemento)
print(len(frutas))   # 3

frutas.append("kiwi")    # añadir al final
frutas.remove("banana")  # eliminar por valor
frutas.pop(0)            # eliminar por índice

# Recorrer una lista
for fruta in frutas:
    print(fruta)

# Slicing: obtener una sublista
print(numeros[1:4])   # [2, 3, 4] (desde índice 1 hasta 3, el 4 no se incluye)
print(numeros[:3])    # [1, 2, 3] (desde el inicio hasta el índice 2)
print(numeros[2:])    # [3, 4, 5] (desde el índice 2 hasta el final)
// JavaScript: arrays
const frutas = ["manzana", "banana", "naranja"];

console.log(frutas[0]);         // "manzana"
console.log(frutas.length);     // 3
frutas.push("kiwi");            // añadir al final
frutas.splice(1, 1);            // eliminar desde índice 1, 1 elemento
console.log(frutas.slice(1, 3));// sublista: elementos 1 y 2

// Recorrer
frutas.forEach(fruta => console.log(fruta));
const enMayusculas = frutas.map(f => f.toUpperCase());
const largas = frutas.filter(f => f.length > 5);

Diccionarios y objetos

# Python: diccionarios (clave → valor)
usuario = {
    "nombre": "Ana García",
    "edad":   25,
    "activo": True,
    "ciudad": "Madrid"
}

print(usuario["nombre"])   # "Ana García"
print(usuario.get("email", "sin email"))  # "sin email" (valor por defecto si no existe)

usuario["email"] = "ana@mail.com"  # añadir nueva clave
del usuario["ciudad"]              # eliminar una clave

# Recorrer un diccionario
for clave, valor in usuario.items():
    print(f"{clave}: {valor}")

# Comprobar si existe una clave
if "email" in usuario:
    print("Tiene email registrado")
// JavaScript: objetos
const usuario = {
    nombre: "Ana García",
    edad:   25,
    activo: true,
    ciudad: "Madrid"
};

console.log(usuario.nombre);        // "Ana García" (notación de punto)
console.log(usuario["nombre"]);     // "Ana García" (notación de corchetes)
console.log(usuario.email ?? "sin email");  // "sin email" (operador nullish coalescing)

usuario.email = "ana@mail.com";    // añadir propiedad
delete usuario.ciudad;             // eliminar propiedad

// Recorrer
Object.entries(usuario).forEach(([clave, valor]) => console.log(`${clave}: ${valor}`));

Tuplas y conjuntos

# Python: tuplas (como las listas pero inmutables: no se pueden modificar)
coordenadas = (40.4168, -3.7038)   # latitud y longitud de Madrid
rgb         = (255, 128, 0)

print(coordenadas[0])   # 40.4168
# coordenadas[0] = 50   → TypeError: las tuplas no son modificables

# Son útiles para valores que no deben cambiar: coordenadas, fechas fijas, constantes

# Conjuntos (set): sin duplicados, sin orden garantizado
colores = {"rojo", "verde", "azul", "rojo"}
print(colores)   # {"rojo", "verde", "azul"} ← el duplicado se elimina

# Operaciones de conjuntos
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
print(a & b)     # {3, 4}     intersección
print(a | b)     # {1,2,3,4,5,6} unión
print(a - b)     # {1, 2}    diferencia

Conversión entre tipos

A veces necesitas convertir un valor de un tipo a otro. A esto se le llama casting o conversión de tipos.

# Python: conversión de tipos
# String a número
edad_texto = "25"
edad_num   = int(edad_texto)      # 25 (entero)
precio_txt = "19.99"
precio_num = float(precio_txt)    # 19.99 (decimal)

# Número a string
numero   = 42
texto    = str(numero)            # "42"
print("El valor es: " + texto)    # concatenar strings

# Comprobación antes de convertir (para evitar errores)
entrada = input("Introduce tu edad: ")
if entrada.isdigit():
    edad = int(entrada)
    print(f"Tienes {edad} años")
else:
    print("Eso no es un número válido")

# Boolean a número
print(int(True))    # 1
print(int(False))   # 0
print(bool(0))      # False
print(bool(1))      # True
print(bool(""))     # False
print(bool("hola")) # True
// JavaScript: conversión de tipos
// String a número
let texto = "25";
let numero = Number(texto);     // 25
let numero2 = parseInt("25px"); // 25 (ignora los caracteres no numéricos del final)
let decimal = parseFloat("3.14"); // 3.14

// Número a string
let n = 42;
let s = String(n);              // "42"
let s2 = n.toString();          // "42"
let s3 = n + "";                // "42" (truco: concatenar con string vacío)

// Coerción implícita (JavaScript la hace automáticamente y puede sorprender)
console.log("5" + 3);    // "53" (convierte 3 a string y concatena)
console.log("5" - 3);    // 2   (convierte "5" a número y resta)
console.log("5" * 3);    // 15  (convierte "5" a número y multiplica)
// Por eso en JavaScript es importante entender bien los tipos

Constantes: variables que no cambian

A veces quieres guardar un valor que nunca debe cambiar a lo largo del programa: el valor de PI, el número máximo de intentos de login, la URL base de la API.

# Python: no tiene constantes reales, se usa la convención de escribirlas en MAYÚSCULAS
PI               = 3.14159
MAX_INTENTOS     = 3
URL_BASE_API     = "https://api.ejemplo.com/v1"
MONEDA_DEFAULT   = "EUR"

# El lenguaje no impide cambiarlas, pero la convención avisa a otros desarrolladores
# de que no deben modificarse
// JavaScript: const declara una variable que no puede reasignarse
const PI = 3.14159;
const MAX_INTENTOS = 3;

// PI = 3;   → TypeError: Assignment to constant variable

// Importante: const no hace el valor inmutable, solo la referencia
const frutas = ["manzana", "banana"];
frutas.push("naranja");  // esto SÍ funciona: modificamos el array, no la variable
// frutas = ["kiwi"];   → esto NO funciona: intentamos reasignar la variable
// Java: la palabra clave 'final' declara una constante
final double PI = 3.14159;
final int MAX_INTENTOS = 3;
// PI = 3;  → error de compilación

 

Los errores más comunes con variables y tipos

Confundir = con ==. El signo = asigna un valor. El doble == compara si dos valores son iguales. Es uno de los errores más frecuentes al empezar.

# Python
edad = 25       # asigna el valor 25 a la variable edad
edad == 25      # compara si edad es igual a 25 (devuelve True, pero no hace nada)
if edad == 25:  # condición: entra si edad es igual a 25
    print("Tienes 25 años")

Usar una variable antes de asignarle un valor.

# Python
print(resultado)   # NameError: name 'resultado' is not defined
resultado = 42

 

Operar con tipos incompatibles.

# Python
edad = input("¿Cuántos años tienes? ")   # input() siempre devuelve string
siguiente = edad + 1   # TypeError: no puedes sumar string y int

# Solución: convertir antes de operar
siguiente = int(edad) + 1

 

No distinguir entre ningún valor y el valor cero o falso.

# Python
resultado = 0
if not resultado:
    print("No hay resultado")   # ¡Esto se ejecuta aunque resultado sea 0!

# Si 0 es un resultado válido, compara explícitamente con None:
if resultado is None:
    print("No hay resultado")

 

Resumen

  • Una variable es un nombre que apunta a un valor guardado en memoria. Se crea con el operador de asignación =.
  • Los tipos de datos más comunes son: enteros (int), decimales (float), texto (str), booleanos (bool) y el valor nulo (None/null).
  • Las colecciones permiten guardar múltiples valores: listas/arrays (ordenados, modificables), diccionarios/objetos (clave-valor), tuplas (inmutables) y conjuntos (sin duplicados).
  • Los lenguajes de tipado dinámico (Python, JavaScript) deducen el tipo automáticamente. Los de tipado estático (Java, TypeScript) requieren declararlo explícitamente y son más seguros ante errores de tipo.
  • La conversión de tipos permite pasar un valor de un tipo a otro: int(), str(), float() en Python; Number(), String(), parseInt() en JavaScript.
  • El error más frecuente al empezar es confundir = (asignación) con == (comparación).

¿Te ha gustado esta entrada?

Compártela con tus compañeros para que también sigan aprendiendo.

Comunidad y Comentarios

0 COMENTARIOS

No hay comentarios todavía. Sé el primero en compartir tu opinión.

Escribe tu opinión
Respondiendo a