Volver a Introducción
Introducción

Python y JavaScript lado a lado

La tabla de equivalencias que vas a consultar todo el curso, más las trampas donde el mismo algoritmo pasa en un lenguaje y falla en el otro.

8 min de lectura

Cada problema del curso se puede resolver en Python o en JavaScript. Esta lección es de consulta: vuelve cuando no recuerdes cómo se hace algo en el otro lenguaje.

Al final están las cuatro diferencias que producen bugs reales, no solo cambios de sintaxis. Esas conviene leerlas una vez completas.

Estructuras de datos

NecesitasPythonJavaScript
Array dinámicolista = []const arr = []
Largolen(lista)arr.length
Agregar al finallista.append(x)arr.push(x)
Sacar del finallista.pop()arr.pop()
Diccionariod = {}const m = new Map()
Conjuntos = set()const s = new Set()
Stackuna lista con append y popun array con push y pop
Colacollections.dequearray con shift (lento) o dos punteros
Heapheapqno existe, se implementa
Tupla inmutable(a, b)[a, b] o Object.freeze

Diccionarios

OperaciónPythonJavaScript
Creard = {}const m = new Map()
Guardard[k] = vm.set(k, v)
Leerd[k]m.get(k)
Leer con defaultd.get(k, 0)m.get(k) ?? 0
¿Existe?k in dm.has(k)
Borrardel d[k]m.delete(k)
Cantidadlen(d)m.size
Recorrerfor k, v in d.items():for (const [k, v] of m)
Contar frecuenciasCounter(lista)recorrer con set y get

El patrón de contar, que aparece en decenas de problemas:

from collections import defaultdict
frecuencia = defaultdict(int)
for x in lista:
    frecuencia[x] += 1
const frecuencia = new Map();
for (const x of lista) {
  frecuencia.set(x, (frecuencia.get(x) ?? 0) + 1);
}

Usa Map y no un objeto {}. Un objeto convierte todas las claves a string, así que 1 y "1" colisionan, y además pierde el orden de inserción para claves numéricas. Map acepta cualquier tipo como clave y conserva el orden.

Conjuntos

OperaciónPythonJavaScript
Crear vacíos = set()const s = new Set()
Desde listaset(lista)new Set(lista)
Agregars.add(x)s.add(x)
¿Está?x in ss.has(x)
Quitars.discard(x)s.delete(x)
Cantidadlen(s)s.size
A listalist(s)[...s]

Strings

OperaciónPythonJavaScript
Largolen(s)s.length
Carácter en is[i]s[i]
Subcadenas[i:j]s.slice(i, j)
Últimos ks[-k:]s.slice(-k)
Invertirs[::-1][...s].reverse().join("")
Separars.split(",")s.split(",")
Unir"".join(partes)partes.join("")
A minúsculass.lower()s.toLowerCase()
¿Es letra o dígito?c.isalnum()/[a-z0-9]/i.test(c)
Carácter a númeroord(c)c.charCodeAt(0)
Número a carácterchr(n)String.fromCharCode(n)
Posición en el alfabetoord(c) - ord('a')c.charCodeAt(0) - 97

En los dos lenguajes los strings son inmutables, así que concatenar dentro de un loop es O(n²) en ambos. Acumula en una lista y une al final.

Ordenar

NecesitasPythonJavaScript
Copia ordenadasorted(arr)[...arr].sort((a,b) => a-b)
En el lugararr.sort()arr.sort((a,b) => a-b)
Descendentesorted(arr, reverse=True)[...arr].sort((a,b) => b-a)
Por una clavesorted(arr, key=lambda x: x[1])[...arr].sort((a,b) => a[1]-b[1])
Dos criterioskey=lambda x: (x[1], x[0])(a,b) => (a[1]-b[1]) || (a[0]-b[0])

Loops y recorridos

NecesitasPythonJavaScript
De 0 a n-1for i in range(n):for (let i = 0; i < n; i++)
Sobre los valoresfor x in arr:for (const x of arr)
Índice y valorfor i, x in enumerate(arr):for (const [i, x] of arr.entries())
Hacia atrásfor i in range(n-1, -1, -1):for (let i = n-1; i >= 0; i--)
Dos listas a la vezfor a, b in zip(xs, ys):xs.forEach((a, i) => ...) con ys[i]
Transformar[f(x) for x in arr]arr.map(f)
Filtrar[x for x in arr if p(x)]arr.filter(p)
Sumar todosum(arr)arr.reduce((a,b) => a+b, 0)
Máximomax(arr)Math.max(...arr)

Math.max(...arr) se rompe con arrays muy grandes porque el spread agota la pila de argumentos. Con más de unos 100.000 elementos, usa un loop o reduce.

Números

NecesitasPythonJavaScript
División enteraa // bMath.floor(a / b)
División reala / ba / b
Potenciaa ** ba ** b
Valor absolutoabs(x)Math.abs(x)
Infinitofloat('inf')Infinity
Menos infinitofloat('-inf')-Infinity
Entero más grande segurono hay límiteNumber.MAX_SAFE_INTEGER

Matrices

Crear una matriz de ceros de f filas por c columnas:

matriz = [[0] * c for _ in range(f)]
const matriz = Array.from({ length: f }, () => new Array(c).fill(0));

Las cuatro trampas que sí producen bugs

Lo anterior son diferencias de sintaxis: si te equivocas, el programa falla y lo ves. Estas cuatro son peores, porque el código corre y devuelve un resultado incorrecto.

1. El módulo con negativos

-3 % 5   # 2 en Python
-3 % 5   // -3 en JavaScript

Python siempre devuelve un resultado con el signo del divisor. JavaScript conserva el signo del dividendo. Cuando usas el módulo como clave de un diccionario, en JavaScript terminas con -3 y 2 como claves distintas cuando deberían ser la misma.

La normalización:

const resto = ((x % k) + k) % k;

Aparece en el problema de subarrays divisibles por K, y es la causa típica de que el mismo algoritmo pase en Python y falle en JavaScript.

2. La división entera con negativos

-7 // 2   # -4, redondea hacia abajo
Math.floor(-7 / 2)   // -4, igual
Math.trunc(-7 / 2)   // -3, corta hacia cero

Math.floor es el equivalente de //. Si usas Math.trunc o | 0, los negativos salen distintos. Aparece al calcular el punto medio en búsqueda binaria sobre rangos que pueden ser negativos.

3. Copias contra referencias

b = a          # b es el mismo objeto que a
b = a[:]       # copia superficial
b = [fila[:] for fila in a]   # copia de una matriz
const b = a;              // misma referencia
const b = [...a];         // copia superficial
const b = a.map(f => [...f]);   // copia de una matriz

En backtracking esto muerde siempre: si agregas el camino actual al resultado sin copiarlo, todas las entradas del resultado apuntan al mismo array y terminan vacías cuando el algoritmo deshace sus pasos.

4. El heap no existe en JavaScript

Python trae heapq, que es un min-heap sobre una lista normal:

import heapq
h = []
heapq.heappush(h, 5)
heapq.heappush(h, 1)
menor = heapq.heappop(h)   # 1

Para un max-heap, empuja los valores negados.

JavaScript no tiene nada equivalente en el lenguaje ni en la librería estándar. En una entrevista de JavaScript tienes tres salidas: implementarlo (está en la lección de heap de este curso), usar un array ordenado si las inserciones son pocas, o decir en voz alta "aquí usaría una cola de prioridad" y seguir. La tercera opción es aceptable en la mayoría de entrevistas si explicas la complejidad que tendría.

Cuál elegir

Para entrevistas, Python suele convenir: menos código, sin comparadores en el sort, heapq incluido, y enteros sin límite de tamaño.

JavaScript conviene si es tu lenguaje diario y vas a un puesto de frontend o de Node, porque la fluidez pesa más que la comodidad de la librería. Lo que no conviene es elegir un lenguaje que no dominas porque "es mejor para entrevistas". Perder tiempo con la sintaxis cuesta más que escribir un heap a mano.

Inicia sesión para guardar el progreso de esta lección.