Desplazando ceros 0️⃣

En los comentarios presentaron casi todas las formas posibles de resolver el problema.

Por supuesto, el patrón clásico para resolverlo aquí son dos punteros.
Aquí está la solución ideal con complejidad O(n) en tiempo y O(1) en memoria:

def move_zeroes(nums: list[int]) -> None:
insert_pos = 0

for i in range(len(nums)):
if nums[i] != 0:
# Intercambiamos el elemento no nulo con el "cero izquierdo"
nums[insert_pos], nums[i] = nums[i], nums[insert_pos]
insert_pos += 1


Sin asignaciones adicionales. Sin pop() desde el medio de la lista. Recorremos el array exactamente una vez. La variable insert_pos siempre apunta al primer cero disponible. En cuanto encontramos un número distinto de cero, simplemente los intercambiamos gracias al mecanismo incorporado de desempaquetado de tuplas en Python.

🐍 Pero no sería interesante sin algo más ingenioso. Aquí tienen un flex pitónico en una línea sin generadores:
nums.sort(key=bool, reverse=True)


¿Cómo funciona? bool(0) da False, los demás números — True. La ordenación incorporada Timsort en Python es estable — conserva estrictamente el orden original de los elementos iguales. Todos los True (números) se moverán a la izquierda, manteniendo su orden, y todos los False (ceros) volarán a la derecha.

Sí, formalmente aquí la complejidad es O(n log n), que algorítmicamente es peor que dos punteros. Pero debido a que Timsort está escrito en C alucinante, en listas reales de pequeño volumen este código superará físicamente en velocidad de ejecución a los bucles en Python puro.

#algosobresaliente