Python – Crear archivo ZIP

zipfile viene con Python. Para comprimir una carpeta solo hay que acordarse de una cosa: guardar las rutas relativas, no las absolutas.

Una carpeta entera

import zipfile
from pathlib import Path

origen = Path("origen")

with zipfile.ZipFile("copia.zip", "w", compression=zipfile.ZIP_DEFLATED) as zf:
    for p in sorted(origen.rglob("*")):
        if p.is_file():
            zf.write(p, arcname=p.relative_to(origen))
salidacopia.zip: 330 bytes

arcname es lo importante. Es el nombre con el que el archivo queda dentro del ZIP. Sin él, Python guarda la ruta tal como se la pasas; con rutas absolutas como las de la versión anterior de esta página, quien lo descomprimiera se encontraría las carpetas home/decodigo/Documentos/python/…. relative_to(origen) deja a.txt y sub/c.txt.

Y compression=zipfile.ZIP_DEFLATED hace falta: por omisión zipfile no comprime, solo empaqueta.

Lo que ha quedado dentro

with zipfile.ZipFile("copia.zip") as zf:
    for info in zf.infolist():
        print(f"  {info.filename:<10} {info.file_size:>5} -> {info.compress_size:>4} bytes")
salidaa.txt       1600 ->   23 bytes
  b.txt          8 ->   10 bytes
  sub/c.txt      7 ->    9 bytes

El primer archivo, la misma línea repetida doscientas veces, se queda en 23 bytes. Los dos pequeños crecen: no hay nada que repetir, y el algoritmo añade su propia cabecera. Comprimir compensa con texto grande y repetitivo; con imágenes o vídeos, que ya vienen comprimidos, no gana nada.

La forma corta

import shutil
shutil.make_archive("en_una_linea", "zip", origen)
salidamake_archive: ['sub/', 'b.txt', 'a.txt', 'sub/c.txt']

Comprime la carpeta entera, con rutas relativas y comprimiendo de verdad. Si no necesitas elegir qué entra, es la opción. Además de "zip" acepta "tar", "gztar" y "xztar".

La versión anterior importaba zlib dentro de un try para decidir si comprimía. No hace falta: zlib viene con Python en cualquier instalación normal.

Más información en inglés: Create ZIP files in Python.

Todo el código se ejecutó con Python 3.14 en un contenedor limpio antes de publicar esta página; las salidas están copiadas de esa ejecución.