Convertir CSV a JSON en Python — Guía json.dumps()
Usa el CSV to JSON gratuito directamente en tu navegador — sin instalación.
Probar CSV to JSON online →Los archivos CSV aparecen en todas partes — informes exportados, volcados de bases de datos, extractos de registros — y tarde o temprano necesitas convertir ese CSV a JSON en Python. La biblioteca estándar gestiona esto con dos módulos: csv.DictReader convierte cada fila en un dict Python, y json.dumps() serializa esos dicts a una cadena JSON. Para una conversión rápida sin código, el conversor CSV a JSON lo hace al instante en el navegador. Esta guía cubre el proceso completo por código: json.dump() vs json.dumps(), escritura de JSON en archivos, serialización de dataclasses, conversión de tipos para valores CSV, gestión de datetime y Decimal, y alternativas de alto rendimiento como orjson. Todos los ejemplos tienen como objetivo Python 3.10+.
- ✓csv.DictReader produce una lista de dicts — serializa la lista completa con json.dump(rows, f, indent=2) para escribir un archivo JSON.
- ✓json.dump() escribe directamente en un objeto de archivo. json.dumps() devuelve una cadena. Elige el correcto y evitas una copia innecesaria.
- ✓Los valores CSV son siempre cadenas. Convierte las columnas numéricas explícitamente (int(), float()) antes de serializar a JSON.
- ✓Pasa ensure_ascii=False a json.dumps() para preservar caracteres Unicode — nombres acentuados, texto CJK — en la salida.
- ✓Para datetime, UUID o Decimal provenientes de CSV, usa el parámetro default= con una función de respaldo personalizada.
order_id,product,quantity,price ORD-7291,Wireless Keyboard,2,49.99 ORD-7292,USB-C Hub,1,34.50
[
{
"order_id": "ORD-7291",
"product": "Wireless Keyboard",
"quantity": "2",
"price": "49.99"
},
{
"order_id": "ORD-7292",
"product": "USB-C Hub",
"quantity": "1",
"price": "34.50"
}
]"2", "49.99") en la salida sin procesar. CSV no tiene sistema de tipos — cada valor es una cadena. Cómo solucionar esto se cubre en la sección de conversión de tipos más abajo.json.dumps() — Serializar un Dict Python a una Cadena JSON
El módulo json viene incluido en toda instalación Python — no se requiere pip install. json.dumps(obj) toma un objeto Python (dict, list, string, número, bool o None) y devuelve un str que contiene JSON válido. Un diccionario Python se parece a un objeto JSON, pero son fundamentalmente diferentes: un dict es una estructura de datos Python en memoria, y una cadena JSON es texto serializado. Llamar a json.dumps() cierra esa brecha.
Ejemplo mínimo — Una fila CSV a JSON
import json
# Una sola fila CSV representada como dict Python
server_entry = {
"hostname": "web-prod-03",
"ip_address": "10.0.12.47",
"port": 8080,
"region": "eu-west-1"
}
# Convertir dict a cadena JSON
json_string = json.dumps(server_entry)
print(json_string)
# {"hostname": "web-prod-03", "ip_address": "10.0.12.47", "port": 8080, "region": "eu-west-1"}
print(type(json_string))
# <class 'str'>Eso produce JSON compacto en una sola línea — bueno para payloads y almacenamiento, difícil de leer. Añade indent=2 para obtener una salida legible por humanos:
import json
server_entry = {
"hostname": "web-prod-03",
"ip_address": "10.0.12.47",
"port": 8080,
"region": "eu-west-1"
}
pretty_json = json.dumps(server_entry, indent=2)
print(pretty_json)
# {
# "hostname": "web-prod-03",
# "ip_address": "10.0.12.47",
# "port": 8080,
# "region": "eu-west-1"
# }Dos parámetros más que uso en casi cada llamada: sort_keys=True ordena las claves del diccionario alfabéticamente (muy útil para comparar archivos JSON entre versiones), y ensure_ascii=False preserva los caracteres no ASCII en lugar de escaparlos a secuencias \uXXXX.
import json
warehouse_record = {
"sku": "WH-9031",
"location": "Valencia Almacén 3",
"quantity": 240,
"last_audit": "2026-03-10"
}
output = json.dumps(warehouse_record, indent=2, sort_keys=True, ensure_ascii=False)
print(output)
# {
# "last_audit": "2026-03-10",
# "location": "Valencia Almacén 3",
# "quantity": 240,
# "sku": "WH-9031"
# }Una nota sobre el parámetro separators: el valor por defecto es (", ", ": "), que añade espacios tras las comas y los dos puntos. Para la salida más compacta posible (útil al incrustar JSON en parámetros de URL o al reducir bytes en respuestas de API), pasa separators=(",", ":").
json.dumps() convierte el Python True al JSON true, None a null, y envuelve las cadenas en comillas dobles (Python permite comillas simples, JSON no). Usa siempre json.dumps() para producir JSON válido — no confíes en str() ni en repr().csv.DictReader a archivo JSON — El Pipeline Completo
La tarea más habitual en producción es leer un archivo CSV completo y guardarlo como JSON. Aquí está el script de extremo a extremo en menos de 10 líneas. csv.DictReader produce un iterador de objetos dict — uno por fila, usando la primera línea como claves. Envolverlo en list() recoge todas las filas en una lista Python, que se serializa como un array JSON.
import csv
import json
# Paso 1: Leer filas CSV en una lista de dicts
with open("inventory.csv", "r", encoding="utf-8") as csv_file:
rows = list(csv.DictReader(csv_file))
# Paso 2: Escribir la lista como archivo JSON
with open("inventory.json", "w", encoding="utf-8") as json_file:
json.dump(rows, json_file, indent=2, ensure_ascii=False)
print(f"Convertidas {len(rows)} filas a inventory.json")Dos llamadas a open(): una para leer el CSV, otra para escribir el JSON. Ese es todo el patrón. Fíjate que se usa json.dump() (sin la s) — escribe directamente en el manejador de archivo. Usar json.dumps() devolvería una cadena que después tendrías que escribir por separado con f.write(). json.dump() es más eficiente en memoria porque transmite la salida en lugar de construir la cadena completa en memoria primero.
Cuando necesitas el JSON como cadena en lugar de como archivo — para incrustarlo en un payload de API, imprimirlo en stdout o insertarlo en una columna de base de datos — cambia a json.dumps():
import csv
import json
with open("sensors.csv", "r", encoding="utf-8") as f:
rows = list(csv.DictReader(f))
# Obtener el JSON como cadena en lugar de escribirlo en un archivo
json_payload = json.dumps(rows, indent=2)
print(json_payload)
# [
# {
# "sensor_id": "TMP-4401",
# "location": "Edificio 7 - Piso 2",
# "reading": "22.4",
# "unit": "celsius"
# },
# ...
# ]Fila única vs. conjunto completo: si llamas a json.dumps(single_dict) obtienes un objeto JSON ({...}). Llama a json.dumps(list_of_dicts) y obtienes un array JSON ([{...}, {...}]). La forma del contenedor exterior depende de lo que pases. La mayoría de los consumidores esperan un array para datos tabulares.
Gestión de Valores No Cadena — Conversión de Tipos desde CSV
Aquí está lo que le pilla a todo el mundo la primera vez: csv.DictReader devuelve cada valor como cadena. El número 42 en tu CSV se convierte en la cadena "42" en el dict. Si lo serializas directamente con json.dumps(), tu JSON tendrá "quantity": "42" en lugar de "quantity": 42. Las APIs que validan tipos rechazarán esto. Necesitas hacer la conversión de tipos de forma explícita.
import csv
import json
def coerce_types(row: dict) -> dict:
"""Convierte valores de cadena a los tipos Python apropiados."""
return {
"sensor_id": row["sensor_id"],
"location": row["location"],
"temperature": float(row["temperature"]),
"humidity": float(row["humidity"]),
"battery_pct": int(row["battery_pct"]),
"active": row["active"].lower() == "true",
}
with open("sensor_readings.csv", "r", encoding="utf-8") as f:
rows = [coerce_types(row) for row in csv.DictReader(f)]
print(json.dumps(rows[0], indent=2))
# {
# "sensor_id": "TMP-4401",
# "location": "Edificio 7 - Piso 2",
# "temperature": 22.4,
# "humidity": 58.3,
# "battery_pct": 87,
# "active": true
# }Ahora temperature es un float, battery_pct es un entero y active es un booleano en la salida JSON. La función de conversión es específica del esquema de tu CSV — no hay una forma genérica de inferir tipos a partir de datos CSV, así que escribo una función por cada formato CSV.
Serialización de Objetos Personalizados y Tipos No Estándar
El módulo json de Python no puede serializar datetime, UUID, Decimal ni clases personalizadas de forma nativa. Llamar a json.dumps() con cualquiera de estos lanza un TypeError. Hay dos enfoques para gestionar esto.
Enfoque 1: El parámetro default=
Pasa una función a default= que convierta los tipos desconocidos a algo serializable. Esta función solo se llama para los objetos que el codificador JSON no sabe gestionar.
import json
from datetime import datetime
from decimal import Decimal
from uuid import UUID
def json_serial(obj):
"""Serializador de respaldo para tipos no estándar."""
if isinstance(obj, datetime):
return obj.isoformat()
if isinstance(obj, UUID):
return str(obj)
if isinstance(obj, Decimal):
return float(obj)
raise TypeError(f"Type {type(obj).__name__} is not JSON serializable")
transaction = {
"txn_id": UUID("a1b2c3d4-e5f6-7890-abcd-ef1234567890"),
"amount": Decimal("149.99"),
"currency": "EUR",
"processed_at": datetime(2026, 3, 15, 14, 30, 0),
"gateway": "stripe",
}
print(json.dumps(transaction, indent=2, default=json_serial))
# {
# "txn_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
# "amount": 149.99,
# "currency": "EUR",
# "processed_at": "2026-03-15T14:30:00",
# "gateway": "stripe"
# }TypeError al final de tu función default= para los tipos no reconocidos. Si devuelves None o los omites en silencio, obtienes null en la salida sin ninguna indicación de que se han perdido datos.Enfoque 2: Dataclasses con asdict()
Los dataclasses de Python dan a tus filas CSV una definición de tipo adecuada. Usa dataclasses.asdict() para convertir una instancia de dataclass a un dict plano y después pásalo a json.dumps().
import json
from dataclasses import dataclass, asdict
from datetime import datetime
@dataclass
class ShipmentRecord:
tracking_id: str
origin: str
destination: str
weight_kg: float
shipped_at: datetime
def json_serial(obj):
if isinstance(obj, datetime):
return obj.isoformat()
raise TypeError(f"Not serializable: {type(obj).__name__}")
shipment = ShipmentRecord(
tracking_id="SHP-9827",
origin="Buenos Aires",
destination="Madrid",
weight_kg=1240.5,
shipped_at=datetime(2026, 3, 12, 8, 0, 0),
)
print(json.dumps(asdict(shipment), indent=2, default=json_serial))
# {
# "tracking_id": "SHP-9827",
# "origin": "Buenos Aires",
# "destination": "Madrid",
# "weight_kg": 1240.5,
# "shipped_at": "2026-03-12T08:00:00"
# }asdict() convierte recursivamente los dataclasses anidados en dicts. Si tu dataclass contiene una lista de otros dataclasses, todo el árbol se convierte — no se necesita código adicional.Referencia de Parámetros de json.dumps()
Lista completa de los argumentos de palabra clave aceptados por json.dumps() y json.dump(). Ambas funciones aceptan parámetros idénticos — json.dump() recibe un argumento adicional inicial para el objeto de archivo.
csv.DictReader — Lectura de CSV en Dicts Python
csv.DictReader es la otra mitad del pipeline CSV a JSON. Envuelve un objeto de archivo y produce un dict por fila, usando la primera línea como nombres de campo. En comparación con csv.reader (que produce listas simples), DictReader da acceso a las columnas por nombre — sin índices mágicos como row[3].
import csv
import json
# Archivo separado por tabulaciones desde una exportación de base de datos
with open("user_sessions.tsv", "r", encoding="utf-8") as f:
reader = csv.DictReader(f, delimiter="\t")
sessions = list(reader)
print(json.dumps(sessions[:2], indent=2))
# [
# {
# "session_id": "sess_8f2a91bc",
# "user_id": "usr_4421",
# "started_at": "2026-03-15T09:12:00Z",
# "duration_sec": "342",
# "pages_viewed": "7"
# },
# {
# "session_id": "sess_3c7d44ef",
# "user_id": "usr_1187",
# "started_at": "2026-03-15T09:14:22Z",
# "duration_sec": "128",
# "pages_viewed": "3"
# }
# ]csv.DictReader lee el archivo de forma perezosa — produce filas de una en una. Llamar a list(reader) carga todas las filas en memoria. Para archivos con millones de filas, procesa las filas de forma continua en lugar de recopilarlas todas.Convertir CSV desde un Archivo y una Respuesta de API
Dos escenarios de producción: leer un archivo CSV del disco y convertirlo, y obtener datos CSV desde un endpoint de API (muchos servicios de informes devuelven CSV). Ambos necesitan un manejo adecuado de errores.
Leer archivo CSV → Convertir → Escribir JSON
import csv
import json
import sys
def csv_to_json_file(csv_path: str, json_path: str) -> int:
"""Convierte un archivo CSV a JSON. Devuelve el número de filas escritas."""
try:
with open(csv_path, "r", encoding="utf-8") as f:
rows = list(csv.DictReader(f))
except FileNotFoundError:
print(f"Error: {csv_path} not found", file=sys.stderr)
sys.exit(1)
except csv.Error as e:
print(f"CSV parse error in {csv_path}: {e}", file=sys.stderr)
sys.exit(1)
with open(json_path, "w", encoding="utf-8") as f:
json.dump(rows, f, indent=2, ensure_ascii=False)
return len(rows)
count = csv_to_json_file("fleet_vehicles.csv", "fleet_vehicles.json")
print(f"Wrote {count} records to fleet_vehicles.json")Obtener CSV desde API → Parsear → JSON
import csv
import io
import json
import urllib.request
def fetch_csv_as_json(url: str) -> str:
"""Obtiene CSV desde una URL y lo devuelve como cadena JSON."""
try:
with urllib.request.urlopen(url, timeout=10) as resp:
raw = resp.read().decode("utf-8")
except urllib.error.URLError as e:
raise RuntimeError(f"Failed to fetch {url}: {e}")
reader = csv.DictReader(io.StringIO(raw))
rows = list(reader)
if not rows:
raise ValueError("CSV response was empty or had no data rows")
return json.dumps(rows, indent=2, ensure_ascii=False)
# Ejemplo: endpoint de exportación que devuelve CSV
try:
result = fetch_csv_as_json("https://reports.internal/api/v2/daily-metrics.csv")
print(result)
except (RuntimeError, ValueError) as e:
print(f"Error: {e}")Ambos ejemplos usan encoding="utf-8" explícito en cada apertura de archivo. Esto importa para archivos CSV con caracteres no ASCII — nombres acentuados, direcciones con caracteres especiales, texto CJK. Sin codificación explícita, Python recurre al valor predeterminado del sistema, que en Windows suele ser cp1252 y corromperá silenciosamente los caracteres multibyte.
Verificar la Salida JSON con json.loads()
Después de convertir CSV a una cadena JSON, puedes verificar el resultado parseándolo de vuelta con json.loads(). Esta verificación de ida y vuelta detecta problemas de codificación, secuencias de escape rotas o concatenaciones accidentales de cadenas que producirían JSON inválido. Envuelve la llamada en un bloque try/except.
import json
json_string = json.dumps({"order_id": "ORD-7291", "total": 129.99})
# Verificar que es JSON válido parseándolo de vuelta
try:
parsed = json.loads(json_string)
print(f"Valid JSON with {len(parsed)} keys")
except json.JSONDecodeError as e:
print(f"Invalid JSON: {e}")
# Valid JSON with 2 keysConversión de CSV a JSON desde la Línea de Comandos
Conversiones rápidas desde la terminal — sin necesidad de un archivo de script. El flag -c de Python ejecuta código en línea, y puedes redirigir el resultado a través de python3 -m json.tool para formatear la salida.
python3 -c " import csv, json, sys rows = list(csv.DictReader(sys.stdin)) json.dump(rows, sys.stdout, indent=2) " < inventory.csv > inventory.json
python3 -c "import csv,json,sys; print(json.dumps(list(csv.DictReader(sys.stdin))))" < data.csv | python3 -m json.tool
python3 -c "import csv,json,sys; json.dump(list(csv.DictReader(sys.stdin)),sys.stdout)" < report.csv | jq .
python3 -m json.tool es el formateador JSON integrado. Lee JSON desde stdin, lo valida y lo imprime con indentación de 4 espacios. Es útil para verificar que tu conversión de CSV a JSON produjo una salida válida. Si prefieres una indentación de 2 espacios o necesitas filtrado, usa jq en su lugar.Alternativa de Alto Rendimiento — orjson
El módulo json integrado funciona bien para la mayoría de archivos CSV. Pero si procesas conjuntos de datos con decenas de miles de filas en un bucle, o tu API necesita serializar datos derivados de CSV en cada petición, orjson es 5–10 veces más rápido. Está escrito en Rust, devuelve bytes en lugar de str, y serializa de forma nativa datetime, UUID y arrays numpy sin necesidad de una función default= personalizada.
pip install orjson
import csv
import orjson
with open("telemetry_events.csv", "r", encoding="utf-8") as f:
rows = list(csv.DictReader(f))
# orjson.dumps() devuelve bytes, no str
json_bytes = orjson.dumps(rows, option=orjson.OPT_INDENT_2)
with open("telemetry_events.json", "wb") as f: # nota: "wb" para bytes
f.write(json_bytes)
print(f"Wrote {len(rows)} events ({len(json_bytes)} bytes)")La API es ligeramente diferente: orjson.dumps() devuelve bytes y usa flags option= en lugar de argumentos de palabra clave. Abre los archivos en modo escritura binaria ("wb") al escribir salida de orjson. Si necesitas una cadena, llama a .decode("utf-8") en el resultado.
Salida con Resaltado de Sintaxis en Terminal — rich
Depurar conversiones de CSV a JSON en la terminal es más fácil con salida coloreada. La biblioteca rich renderiza JSON con resaltado de sintaxis — claves, cadenas, números y booleanos tienen cada uno su propio color.
pip install rich
import csv
import json
from rich.console import Console
from rich.syntax import Syntax
console = Console()
with open("deployment_log.csv", "r", encoding="utf-8") as f:
rows = list(csv.DictReader(f))
json_output = json.dumps(rows[:3], indent=2, ensure_ascii=False)
syntax = Syntax(json_output, "json", theme="monokai", line_numbers=True)
console.print(syntax)rich añade códigos de escape ANSI a la salida. No escribas salida formateada con rich en un archivo ni en una respuesta de API — contendrá caracteres de control invisibles. Usa rich únicamente para la visualización en terminal.Trabajo con Archivos CSV Grandes
Cargar un archivo CSV de 500 MB con list(csv.DictReader(f)) asigna todo el conjunto de datos en memoria, y después json.dump() construye la cadena JSON completa encima de eso. Para archivos de más de 50–100 MB, cambia a un enfoque de streaming o escribe NDJSON (JSON delimitado por nueva línea) — un objeto JSON por línea.
NDJSON — Un Objeto JSON por Línea
import csv
import json
def csv_to_ndjson(csv_path: str, ndjson_path: str) -> int:
"""Convierte CSV a NDJSON procesando una fila a la vez."""
count = 0
with open(csv_path, "r", encoding="utf-8") as infile, \
open(ndjson_path, "w", encoding="utf-8") as outfile:
for row in csv.DictReader(infile):
outfile.write(json.dumps(row, ensure_ascii=False) + "\n")
count += 1
return count
rows_written = csv_to_ndjson("access_log.csv", "access_log.ndjson")
print(f"Wrote {rows_written} lines to access_log.ndjson")
# Cada línea es un objeto JSON independiente:
# {"timestamp":"2026-03-15T09:12:00Z","method":"GET","path":"/api/v2/orders","status":"200"}
# {"timestamp":"2026-03-15T09:12:01Z","method":"POST","path":"/api/v2/payments","status":"201"}Streaming con ijson para Entradas JSON Grandes
import ijson # pip install ijson
def count_high_value_orders(json_path: str, threshold: float) -> int:
"""Cuenta pedidos por encima de un umbral sin cargar el archivo completo."""
count = 0
with open(json_path, "rb") as f:
for item in ijson.items(f, "item"):
if float(item.get("total", 0)) > threshold:
count += 1
return count
# Procesar un archivo JSON de 2 GB con uso de memoria constante
high_value = count_high_value_orders("all_orders.json", 500.0)
print(f"Found {high_value} orders above $500")ijson es para leer archivos JSON grandes de vuelta — para el lado de escritura, el patrón NDJSON anterior mantiene el uso de memoria constante independientemente del tamaño del archivo.Errores Comunes
Problema: json.dumps() devuelve una cadena. Escribirla con f.write() funciona, pero crea una cadena intermedia innecesaria en memoria — un desperdicio para conjuntos de datos grandes.
Solución: Usa json.dump(data, f) para escribir directamente en el objeto de archivo. Transmite la salida sin construir la cadena completa primero.
json_string = json.dumps(rows, indent=2)
with open("output.json", "w") as f:
f.write(json_string) # unnecessary intermediate stringwith open("output.json", "w", encoding="utf-8") as f:
json.dump(rows, f, indent=2, ensure_ascii=False) # direct writeProblema: csv.DictReader devuelve todos los valores como cadenas. La salida JSON contiene "quantity": "5" en lugar de "quantity": 5, lo que rompe los consumidores de API que validan tipos.
Solución: Convierte las columnas numéricas explícitamente con int() o float() antes de serializar.
rows = list(csv.DictReader(f))
json.dumps(rows)
# [{"port": "8080", "workers": "4"}] ← cadenas, no númerosrows = list(csv.DictReader(f))
for row in rows:
row["port"] = int(row["port"])
row["workers"] = int(row["workers"])
json.dumps(rows)
# [{"port": 8080, "workers": 4}] ← enteros correctosProblema: En Windows, la codificación por defecto es cp1252. Los caracteres no ASCII (nombres acentuados, texto CJK) se corrompen silenciosamente o lanzan UnicodeDecodeError.
Solución: Pasa siempre encoding='utf-8' a open() tanto para la lectura del CSV como para la escritura del JSON.
with open("locations.csv", "r") as f: # usa la codificación predeterminada del sistema
rows = list(csv.DictReader(f))with open("locations.csv", "r", encoding="utf-8") as f:
rows = list(csv.DictReader(f))Problema: str(my_dict) produce sintaxis Python (comillas simples, True, None) que no es JSON válido. Las APIs y los parsers JSON lo rechazan.
Solución: Usa siempre json.dumps() para producir JSON válido. Convierte True en true, None en null y usa comillas dobles.
output = str({"active": True, "note": None})
# "{'active': True, 'note': None}" ← NO es JSON válidooutput = json.dumps({"active": True, "note": None})
# '{"active": true, "note": null}' ← JSON válidojson.dumps() vs Alternativas — Comparación Rápida
Para la mayoría de las conversiones de CSV a JSON, la combinación de la biblioteca estándar csv + json es la elección correcta: cero dependencias, incluida con Python, funciona en cualquier lugar. Recurre a orjson cuando el profiling muestre que la serialización es un cuello de botella — la diferencia de velocidad es real a escala. Usa pandas cuando también necesites limpieza de datos, filtrado o agregación antes de convertir a JSON. Si solo necesitas una conversión rápida sin escribir código, el conversor online de CSV a JSON lo hace al instante.
Preguntas Frecuentes
¿Cuál es la diferencia entre json.dump() y json.dumps() en Python?
json.dump(obj, file) escribe la salida JSON directamente en un objeto de tipo archivo (cualquier objeto con un método .write()). json.dumps(obj) devuelve una cadena con formato JSON. Usa json.dump() al escribir en un archivo, json.dumps() cuando necesitas el JSON como cadena Python para registros, incrustarlo en un payload o enviarlo a través de un socket. Ambas funciones aceptan los mismos argumentos de palabra clave (indent, sort_keys, ensure_ascii, default).
¿Cómo convierto un diccionario Python a una cadena JSON?
Llama a json.dumps(tu_dict). El valor de retorno es un str que contiene JSON válido. Añade indent=2 para obtener una salida legible. Si tu diccionario contiene valores no ASCII, pasa ensure_ascii=False para preservar caracteres como letras acentuadas o texto CJK.
import json
server_config = {"host": "api.internal", "port": 8443, "debug": False}
json_string = json.dumps(server_config, indent=2)
print(json_string)
# {
# "host": "api.internal",
# "port": 8443,
# "debug": false
# }¿Cómo guardo una lista de dicts Python como archivo JSON?
Abre un archivo en modo escritura con codificación UTF-8 y llama a json.dump(tu_lista, f, indent=2, ensure_ascii=False). Usa siempre json.dump() (no json.dumps()) para la salida a archivo — escribe directamente en el manejador de archivo sin crear una cadena intermedia en memoria.
import json
records = [
{"order_id": "ORD-4821", "total": 129.99, "currency": "USD"},
{"order_id": "ORD-4822", "total": 89.50, "currency": "EUR"},
]
with open("orders.json", "w", encoding="utf-8") as f:
json.dump(records, f, indent=2, ensure_ascii=False)¿Por qué json.dumps() convierte True en true y None en null?
Los booleanos de Python (True, False) y None no son tokens JSON válidos. La especificación JSON usa las minúsculas true, false y null. json.dumps() gestiona este mapeo automáticamente: True se convierte en true, False en false y None en null. No necesitas convertirlos manualmente. En sentido contrario, json.loads() los mapea de vuelta a tipos Python.
¿Cómo gestiono objetos datetime al convertir datos CSV a JSON?
Pasa una función default= a json.dumps() que convierta los objetos datetime a cadenas ISO 8601. La función default se llama para cualquier objeto que json no puede serializar de forma nativa. Devuelve obj.isoformat() para instancias datetime y lanza TypeError para cualquier otro tipo.
import json
from datetime import datetime
def json_default(obj):
if isinstance(obj, datetime):
return obj.isoformat()
raise TypeError(f"Not serializable: {type(obj)}")
event = {"action": "login", "timestamp": datetime(2026, 3, 15, 9, 30, 0)}
print(json.dumps(event, default=json_default))
# {"action": "login", "timestamp": "2026-03-15T09:30:00"}¿Puedo convertir CSV a JSON sin pandas?
Sí. La biblioteca estándar de Python tiene todo lo que necesitas. Usa csv.DictReader para leer cada fila como un diccionario, recoge las filas en una lista y serializa con json.dump() o json.dumps(). No se requieren bibliotecas de terceros. Pandas solo vale la pena añadirlo si también necesitas limpieza de datos, inferencia de tipos o ya lo usas en otra parte del proyecto.
import csv
import json
with open("inventory.csv", "r", encoding="utf-8") as csv_file:
rows = list(csv.DictReader(csv_file))
with open("inventory.json", "w", encoding="utf-8") as json_file:
json.dump(rows, json_file, indent=2, ensure_ascii=False)Para una alternativa con un solo clic sin escribir nada de Python, prueba el conversor CSV a JSON — pega tus datos CSV y obtén JSON formateado de inmediato.
Herramientas Relacionadas
Maria is a backend developer specialising in Python and API integration. She has broad experience with data pipelines, serialisation formats, and building reliable server-side services. She is an active member of the Python community and enjoys writing practical, example-driven guides that help developers solve real problems without unnecessary theory.
Priya is a data scientist and machine learning engineer who has worked across the full Python data stack — from raw data ingestion and cleaning to model deployment and monitoring. She is passionate about reproducible research, Jupyter-based workflows, and the practical engineering side of ML. She writes about NumPy, Pandas, data serialisation, and the Python patterns that make data pipelines reliable at scale.