Конвертація CSV у JSON на Python — json.dumps()

·Backend Developer·ПеревіреноPriya Sharma·Опубліковано

Використовуйте безкоштовний CSV to JSON прямо в браузері — без встановлення.

Спробувати CSV to JSON онлайн →

CSV-файли трапляються скрізь — експортовані звіти, дампи баз даних, витяги журналів — і рано чи пізно виникає потреба конвертувати CSV у JSON на Python. Стандартна бібліотека вирішує це двома модулями: csv.DictReader перетворює кожен рядок на словник Python, а json.dumps() серіалізує ці словники на рядок JSON. Для швидкої разової конвертації без коду скористайтеся конвертером CSV у JSON — він робить це миттєво у браузері. Цей посібник охоплює повний програмний шлях: json.dump() проти json.dumps(), запис JSON у файли, серіалізацію dataclass, приведення типів для CSV-значень, обробку datetime і Decimal, а також високопродуктивні альтернативи на кшталт orjson. Усі приклади розраховані на Python 3.10+.

  • csv.DictReader повертає список словників — серіалізуйте весь список за допомогою json.dump(rows, f, indent=2), щоб записати JSON-файл.
  • json.dump() записує безпосередньо у файловий об'єкт. json.dumps() повертає рядок. Вибирайте правильний варіант і уникнете зайвого копіювання.
  • Значення CSV — завжди рядки. Явно приводьте числові стовпці (int(), float()) перед серіалізацією в JSON.
  • Передавайте ensure_ascii=False до json.dumps(), щоб зберегти Unicode-символи — імена з діакритикою, CJK-текст — у виводі.
  • Для datetime, UUID або Decimal з CSV використовуйте параметр default= з власною резервною функцією.
Before · json
After · json
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"
  }
]
Примітка:Зверніть увагу, що quantity та price у необробленому виводі відображаються як рядки JSON ("2", "49.99"). У CSV немає системи типів — кожне значення є рядком. Виправлення цього розглядається в розділі про приведення типів нижче.

json.dumps() — Серіалізація словника Python у рядок JSON

Модуль json постачається разом з кожною інсталяцією Python — ніякого pip install не потрібно. json.dumps(obj) приймає об'єкт Python (dict, list, рядок, число, bool або None) і повертає str з валідним JSON. Словник Python виглядає схоже на об'єкт JSON, але вони принципово різні: dict — це структура даних Python у пам'яті, а рядок JSON — серіалізований текст. Виклик json.dumps() усуває цю різницю.

Мінімальний приклад — один рядок CSV у JSON

Python 3.10+
import json

# Один рядок CSV, представлений як словник Python
server_entry = {
    "hostname": "web-prod-03",
    "ip_address": "10.0.12.47",
    "port": 8080,
    "region": "eu-west-1"
}

# Конвертація словника на рядок 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'>

Результат — компактний однорядковий JSON — зручний для пакетів даних і зберігання, але незручний для читання. Додайте indent=2 для зручного виводу:

Python 3.10+ — pretty-printed output
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"
# }

Ще два параметри, які я використовую майже в кожному виклику: sort_keys=True сортує ключі словника за алфавітом (зручно для порівняння JSON-файлів між версіями), а ensure_ascii=False зберігає не-ASCII символи замість екранування їх у послідовності \uXXXX.

Python 3.10+ — sort_keys and ensure_ascii
import json

warehouse_record = {
    "sku": "WH-9031",
    "location": "Склад Київ 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": "Склад Київ 3",
#   "quantity": 240,
#   "sku": "WH-9031"
# }

Коротко про параметр separators: за замовчуванням це (", ", ": "), що додає пробіли після ком та двокрапок. Для максимально компактного виводу (корисно при вбудовуванні JSON у параметри URL або мінімізації розміру відповідей API) передайте separators=(",", ":").

Примітка:Словник Python та об'єкт JSON виглядають майже однаково при виводі. Різниця: json.dumps() перетворює True Python на JSON true, None — на null, а рядки обертає у подвійні лапки (Python допускає одинарні лапки, JSON — ні). Завжди використовуйте json.dumps() для отримання валідного JSON — не покладайтеся на str() чи repr().

csv.DictReader у JSON-файл — Повний конвеєр

Найпоширеніше практичне завдання — читання цілого CSV-файлу та збереження його як JSON. Ось повний скрипт менш ніж у 10 рядках. csv.DictReader повертає ітератор об'єктів dict — по одному на рядок, використовуючи перший рядок як ключі. Обгортання у list() збирає всі рядки у список Python, який серіалізується у JSON-масив.

Python 3.10+ — full CSV to JSON conversion
import csv
import json

# Крок 1: читаємо рядки CSV у список словників
with open("inventory.csv", "r", encoding="utf-8") as csv_file:
    rows = list(csv.DictReader(csv_file))

# Крок 2: записуємо список як JSON-файл
with open("inventory.json", "w", encoding="utf-8") as json_file:
    json.dump(rows, json_file, indent=2, ensure_ascii=False)

print(f"Конвертовано {len(rows)} рядків у inventory.json")

Два виклики open(): один для читання CSV, інший для запису JSON. Ось і весь шаблон. Зверніть увагу, що тут використовується json.dump() (без s) — він записує безпосередньо у файловий дескриптор. Використання json.dumps() повернуло б рядок, який потім потрібно було б окремо записати через f.write(). json.dump() ефективніший за пам'яттю, бо передає вивід потоком замість того, щоб спочатку будувати весь рядок у пам'яті.

Коли потрібен JSON як рядок, а не файл — для вбудовування у пакет даних API, виводу в stdout або вставки у стовпець бази даних — перейдіть на json.dumps():

Python 3.10+ — CSV rows as JSON string
import csv
import json

with open("sensors.csv", "r", encoding="utf-8") as f:
    rows = list(csv.DictReader(f))

# Отримати JSON як рядок замість запису у файл
json_payload = json.dumps(rows, indent=2)
print(json_payload)
# [
#   {
#     "sensor_id": "TMP-4401",
#     "location": "Корпус 7 - Поверх 2",
#     "reading": "22.4",
#     "unit": "celsius"
#   },
#   ...
# ]

Один рядок проти повного набору даних: якщо викликати json.dumps(single_dict), отримаємо JSON-об'єкт ({...}). Виклик json.dumps(list_of_dicts) повертає JSON-масив ([{...}, {...}]). Форма зовнішнього контейнера залежить від того, що передається. Більшість споживачів очікують масив для табличних даних.

Обробка нерядкових значень — Приведення типів з CSV

Ось що збиває з пантелику вперше: csv.DictReader повертає кожне значення як рядок. Число 42 у вашому CSV стає рядком "42" у словнику. Якщо серіалізувати це безпосередньо через json.dumps(), у вашому JSON буде "quantity": "42" замість "quantity": 42. API, що перевіряють типи, відхилять це. Необхідно явно приводити значення.

Python 3.10+ — type coercion for CSV rows
import csv
import json

def coerce_types(row: dict) -> dict:
    """Convert string values to appropriate Python types."""
    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": "Корпус 7 - Поверх 2",
#   "temperature": 22.4,
#   "humidity": 58.3,
#   "battery_pct": 87,
#   "active": true
# }

Тепер temperature є числом з рухомою крапкою, battery_pct — цілим числом, а active — булевим значенням у JSON-виводі. Функція приведення типів прив'язана до схеми вашого CSV — не існує універсального способу визначити типи з CSV-даних, тому я пишу окрему функцію для кожного формату CSV.

Серіалізація власних об'єктів та нестандартних типів

Модуль json Python не може серіалізувати datetime, UUID, Decimalабо власні класи без додаткового налаштування. Виклик json.dumps() для будь-якого з них викидає TypeError. Є два підходи для вирішення цього.

Підхід 1: Параметр default=

Передайте функцію до default=, яка перетворює невідомі типи на щось серіалізоване. Ця функція викликається лише для об'єктів, які JSON-кодувальник не знає, як обробити.

Python 3.10+ — default= for datetime, UUID, Decimal
import json
from datetime import datetime
from decimal import Decimal
from uuid import UUID

def json_serial(obj):
    """Fallback serializer for non-standard types."""
    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 в кінці вашої функції default= для нерозпізнаних типів. Якщо повернути None або мовчки пропустити їх, у виводі з'явиться null без жодного попередження про втрату даних.

Підхід 2: Dataclasses з asdict()

Python dataclasses надають рядкам CSV повноцінне визначення типів. Використовуйте dataclasses.asdict() для перетворення екземпляра dataclass на звичайний словник, потім передайте його до json.dumps().

Python 3.10+ — dataclass serialization
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="Київ",
    destination="Харків",
    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": "Київ",
#   "destination": "Харків",
#   "weight_kg": 1240.5,
#   "shipped_at": "2026-03-12T08:00:00"
# }
Примітка:asdict() рекурсивно конвертує вкладені dataclasses у словники. Якщо ваш dataclass містить список інших dataclasses, все дерево конвертується — додатковий код не потрібен.

Довідник параметрів json.dumps()

Повний список іменованих аргументів, що приймаються json.dumps() та json.dump(). Обидві функції приймають ідентичні параметри — json.dump() приймає додатковий перший аргумент для файлового об'єкта.

Параметр
Тип
За замовчуванням
Опис
obj
Any
(обов'язково)
Об'єкт Python для серіалізації — dict, list, str, int, float, bool, None
indent
int | str | None
None
Кількість пробілів (або рядок) на рівень відступу. None = компактний однорядковий вивід
sort_keys
bool
False
Сортувати ключі словника в алфавітному порядку у виводі
ensure_ascii
bool
True
Екранувати всі не-ASCII символи як \\uXXXX. Встановіть False, щоб виводити UTF-8 безпосередньо
default
Callable | None
None
Функція, що викликається для об'єктів, які не серіалізуються за замовчуванням — поверніть серіалізоване значення або викиньте TypeError
separators
tuple[str, str] | None
None
Замінити (item_separator, key_separator). Використовуйте (",", ":") для компактного виводу без пробілів
skipkeys
bool
False
Пропускати ключі dict, що не є str, int, float, bool або None, замість того щоб викидати TypeError
allow_nan
bool
True
Дозволяти float("nan"), float("inf"), float("-inf"). Встановіть False, щоб викидати ValueError для цих значень
cls
Type[JSONEncoder] | None
None
Власний підклас JSONEncoder замість стандартного

csv.DictReader — Читання CSV у словники Python

csv.DictReader — друга половина конвеєра CSV-у-JSON. Він обгортає файловий об'єкт і повертає по одному dict на рядок, використовуючи перший рядок як назви полів. На відміну від csv.reader (який повертає звичайні списки), DictReader дає іменований доступ до стовпців — ніяких магічних індексів на кшталт row[3].

Python 3.10+ — DictReader with custom delimiter
import csv
import json

# Файл з табуляцією як роздільником із дампу бази даних
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 читає весь файл ліниво — він повертає рядки по одному. Виклик list(reader) завантажує всі рядки в пам'ять. Для файлів з мільйонами рядків обробляйте їх потоково замість того, щоб збирати всі одразу.

Конвертація CSV з файлу та відповіді API

Два виробничі сценарії: читання CSV-файлу з диску та його конвертація, і отримання CSV-даних з кінцевої точки API (чимало сервісів звітності повертають CSV). Обидва потребують належної обробки помилок.

Читання CSV-файлу → Конвертація → Запис JSON

Python 3.10+ — file conversion with error handling
import csv
import json
import sys

def csv_to_json_file(csv_path: str, json_path: str) -> int:
    """Convert a CSV file to JSON. Returns the number of rows written."""
    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"Записано {count} записів у fleet_vehicles.json")

Отримання CSV з API → Парсинг → JSON

Python 3.10+ — API CSV response to JSON
import csv
import io
import json
import urllib.request

def fetch_csv_as_json(url: str) -> str:
    """Fetch CSV from a URL and return it as a JSON string."""
    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)

# Приклад: кінцева точка експорту, що повертає 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}")

В обох прикладах явно вказано encoding="utf-8" при кожному відкритті файлу. Це важливо для CSV-файлів з не-ASCII символами — імена з діакритикою, адреси зі спеціальними символами, CJK-текст. Без явного кодування Python використовує системне кодування за замовчуванням, яке на Windows часто буває cp1252 і мовчки спотворює багатобайтові символи.

Перевірка JSON-виводу за допомогою json.loads()

Після конвертації CSV у рядок JSON можна перевірити результат, розібравши його назад за допомогою json.loads(). Таке кругове перетворення виявляє проблеми з кодуванням, зламані екрановані послідовності або випадкову конкатенацію рядків, що призвела б до невалідного JSON. Огорніть виклик у блок try/except.

Python 3.10+ — round-trip validation
import json

json_string = json.dumps({"order_id": "ORD-7291", "total": 129.99})

# Перевірка валідності JSON шляхом зворотного парсингу
try:
    parsed = json.loads(json_string)
    print(f"Валідний JSON з {len(parsed)} ключами")
except json.JSONDecodeError as e:
    print(f"Невалідний JSON: {e}")
# Валідний JSON з 2 ключами

Конвертація CSV у JSON через командний рядок

Швидка конвертація з терміналу — файл скрипту не потрібен. Прапор -c Python виконує вбудований код, і результат можна передати через конвеєр до python3 -m json.tool для форматованого виводу.

bash — one-liner CSV to JSON
python3 -c "
import csv, json, sys
rows = list(csv.DictReader(sys.stdin))
json.dump(rows, sys.stdout, indent=2)
" < inventory.csv > inventory.json
bash — pipe CSV file and format with json.tool
python3 -c "import csv,json,sys; print(json.dumps(list(csv.DictReader(sys.stdin))))" < data.csv | python3 -m json.tool
bash — convert and validate with jq
python3 -c "import csv,json,sys; json.dump(list(csv.DictReader(sys.stdin)),sys.stdout)" < report.csv | jq .
Примітка:python3 -m json.tool — вбудований засіб форматування JSON. Він читає JSON зі stdin, перевіряє його та виводить з відступом у 4 пробіли. Корисний для перевірки того, що ваша конвертація CSV у JSON дала валідний результат. Якщо потрібен відступ у 2 пробіли або фільтрація, використовуйте натомість jq.

Високопродуктивна альтернатива — orjson

Вбудований модуль json чудово підходить для більшості CSV-файлів. Але якщо ви обробляєте набори даних з десятками тисяч рядків у циклі, або ваш API має серіалізувати дані на основі CSV при кожному запиті, orjson у 5–10 разів швидший. Він написаний на Rust, повертає bytes замість str і нативно серіалізує datetime, UUID та масиви numpy без власної функції default=.

bash — install orjson
pip install orjson
Python 3.10+ — CSV to JSON with orjson
import csv
import orjson

with open("telemetry_events.csv", "r", encoding="utf-8") as f:
    rows = list(csv.DictReader(f))

# orjson.dumps() повертає bytes, а не str
json_bytes = orjson.dumps(rows, option=orjson.OPT_INDENT_2)

with open("telemetry_events.json", "wb") as f:  # зверніть увагу: "wb" для bytes
    f.write(json_bytes)

print(f"Записано {len(rows)} подій ({len(json_bytes)} байт)")

API дещо відрізняється: orjson.dumps() повертає bytes і використовує прапори option= замість іменованих аргументів. Відкривайте файли в режимі бінарного запису ("wb") при записі виводу orjson. Якщо потрібен рядок, викличте .decode("utf-8") на результаті.

Вивід у терміналі з підсвіткою синтаксису — rich

Налагодження конвертацій CSV у JSON в терміналі стає зручнішим із кольоровим виводом. Бібліотека rich відображає JSON з підсвіткою синтаксису — ключі, рядки, числа та булеві значення мають власний колір.

bash — install rich
pip install rich
Python 3.10+ — rich JSON output
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 додає до виводу ANSI-коди escape-послідовностей. Не записуйте форматований rich вивід у файл або відповідь API — він міститиме невидимі керуючі символи. Використовуйте rich лише для відображення в терміналі.

Робота з великими CSV-файлами

Завантаження CSV-файлу розміром 500 МБ за допомогою list(csv.DictReader(f)) виділяє весь набір даних у пам'яті, а потім json.dump() будує повний рядок JSON поверх цього. Для файлів більших за 50–100 МБ перейдіть на потоковий підхід або записуйте NDJSON (JSON з роздільником-новим рядком) — по одному JSON-об'єкту на рядок.

NDJSON — По одному JSON-об'єкту на рядок

Python 3.10+ — streaming CSV to NDJSON
import csv
import json

def csv_to_ndjson(csv_path: str, ndjson_path: str) -> int:
    """Convert CSV to NDJSON, processing one row at a time."""
    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"Записано {rows_written} рядків у access_log.ndjson")
# Кожен рядок є самостійним JSON-об'єктом:
# {"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"}

Потокове читання великих JSON-файлів за допомогою ijson

Python 3.10+ — ijson for reading large JSON
import ijson  # pip install ijson

def count_high_value_orders(json_path: str, threshold: float) -> int:
    """Count orders above a threshold without loading the full file."""
    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

# Обробка JSON-файлу розміром 2 ГБ із постійним використанням пам'яті
high_value = count_high_value_orders("all_orders.json", 500.0)
print(f"Знайдено {high_value} замовлень на суму понад $500")
Примітка:Переходьте на NDJSON або потокову обробку, коли CSV перевищує 50–100 МБ. ijson призначений для читання великих JSON-файлів — для запису використовуйте наведений вище шаблон NDJSON, який підтримує постійне використання пам'яті незалежно від розміру файлу.

Поширені помилки

Використання json.dumps() з наступним окремим записом у файл

Проблема: json.dumps() повертає рядок. Запис через f.write() працює, але створює непотрібний проміжний рядок у пам'яті — марнотратно для великих наборів даних.

Рішення: Використовуйте json.dump(data, f) для безпосереднього запису у файловий об'єкт. Він передає вивід потоком без попередньої побудови повного рядка.

Before · Python
After · Python
json_string = json.dumps(rows, indent=2)
with open("output.json", "w") as f:
    f.write(json_string)  # unnecessary intermediate string
with open("output.json", "w", encoding="utf-8") as f:
    json.dump(rows, f, indent=2, ensure_ascii=False)  # direct write
Забуття про приведення рядкових значень CSV до чисел

Проблема: csv.DictReader повертає всі значення як рядки. JSON-вивід містить "quantity": "5" замість "quantity": 5, що ламає типізовані споживачі API.

Рішення: Явно приводьте числові стовпці через int() або float() перед серіалізацією.

Before · Python
After · Python
rows = list(csv.DictReader(f))
json.dumps(rows)
# [{"port": "8080", "workers": "4"}]  ← strings, not numbers
rows = 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}]  ← proper integers
Пропуск encoding='utf-8' при відкритті файлу

Проблема: На Windows кодування за замовчуванням — cp1252. Не-ASCII символи (імена з діакритикою, CJK-текст) мовчки спотворюються або викидають UnicodeDecodeError.

Рішення: Завжди передавайте encoding='utf-8' до open() як при читанні CSV, так і при записі JSON.

Before · Python
After · Python
with open("locations.csv", "r") as f:  # uses system default encoding
    rows = list(csv.DictReader(f))
with open("locations.csv", "r", encoding="utf-8") as f:
    rows = list(csv.DictReader(f))
Використання str() або repr() замість json.dumps()

Проблема: str(my_dict) виробляє синтаксис Python (одинарні лапки, True, None), що є невалідним JSON. API та JSON-парсери відхиляють його.

Рішення: Завжди використовуйте json.dumps() для отримання валідного JSON. Він перетворює True на true, None на null і використовує подвійні лапки.

Before · Python
After · Python
output = str({"active": True, "note": None})
# "{'active': True, 'note': None}"  ← NOT valid JSON
output = json.dumps({"active": True, "note": None})
# '{"active": true, "note": null}'  ← valid JSON

json.dumps() проти альтернатив — Швидке порівняння

Метод
Вивід
Валідний JSON
Власні типи
Швидкість
Потребує встановлення
json.dumps()
str
через параметр default=
Базова
Ні (stdlib)
json.dump()
запис у файл
через параметр default=
Базова
Ні (stdlib)
csv.DictReader + json
str або файл
через параметр default=
Базова
Ні (stdlib)
pandas to_json()
str або файл
✓ нативний datetime
~2x швидше для великих даних
pip install pandas
orjson.dumps()
bytes
✓ нативний datetime/UUID
у 5–10 разів швидше
pip install orjson
dataclasses.asdict() + json
str
через параметр default=
Базова
Ні (stdlib)
polars write_json()
str або файл
✓ нативний datetime
~3x швидше для великих даних
pip install polars

Для більшості конвертацій CSV у JSON поєднання csv + json зі стандартної бібліотеки є правильним вибором: жодних залежностей, входить до складу Python, працює скрізь. Звертайтеся до orjson, коли профілювання показує, що серіалізація є вузьким місцем — різниця у швидкості реальна при масштабуванні. Використовуйте pandas, коли потрібне очищення даних, фільтрація або агрегація перед конвертацією у JSON. Якщо потрібна швидка конвертація без написання коду, скористайтеся онлайн-конвертером CSV у JSON — він вирішить задачу миттєво.

Поширені запитання

Яка різниця між json.dump() та json.dumps() у Python?

json.dump(obj, file) записує JSON-вивід безпосередньо у файлоподібний об'єкт (будь-що з методом .write()). json.dumps(obj) повертає рядок у форматі JSON. Використовуйте json.dump() для запису у файл, json.dumps() — коли потрібен JSON як рядок Python для журналювання, вбудовування у пакет даних або надсилання через сокет. Обидві функції приймають однакові іменовані аргументи (indent, sort_keys, ensure_ascii, default).

Як перетворити словник Python на рядок JSON?

Викличте json.dumps(your_dict). Результатом є str з валідним JSON. Додайте indent=2 для зручного читання. Якщо словник містить значення не у форматі ASCII, передайте ensure_ascii=False, щоб зберегти символи на кшталт літер із діакритикою або CJK-тексту.

Python 3.10+
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
# }

Як зберегти список словників Python як JSON-файл?

Відкрийте файл для запису з кодуванням UTF-8, потім викличте json.dump(your_list, f, indent=2, ensure_ascii=False). Завжди використовуйте json.dump() (а не json.dumps()) для виводу у файл — він записує безпосередньо у файловий дескриптор без створення проміжного рядка в пам'яті.

Python 3.10+
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)

Чому json.dumps() перетворює True на true, а None на null?

Булеві значення Python (True, False) та None не є валідними токенами JSON. Специфікація JSON використовує true, false та null у нижньому регістрі. json.dumps() виконує це перетворення автоматично — True стає true, False стає false, None стає null. Не потрібно конвертувати їх вручну. У зворотному напрямку json.loads() повертає їх до типів Python.

Як обробляти об'єкти datetime при конвертації CSV-даних у JSON?

Передайте функцію default= до json.dumps(), яка перетворює об'єкти datetime на рядки ISO 8601. Функція default викликається для будь-якого об'єкта, який json не може серіалізувати нативно. Повертайте obj.isoformat() для екземплярів datetime і викидайте TypeError для всього іншого.

Python 3.10+
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"}

Чи можна конвертувати CSV у JSON без pandas?

Так. Стандартна бібліотека Python містить усе необхідне. Використовуйте csv.DictReader для читання кожного рядка як словника, зберіть рядки у список та серіалізуйте за допомогою json.dump() або json.dumps(). Сторонні бібліотеки не потрібні. pandas варто додавати лише якщо вам також потрібне очищення даних, визначення типів або якщо ви вже використовуєте його деінде в проекті.

Python 3.10+
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)

Для однокрокової альтернативи без написання будь-якого Python скористайтеся конвертером CSV у JSON — вставте CSV-дані та отримайте відформатований JSON-вивід миттєво.

Пов'язані інструменти

MS
Maria SantosBackend Developer

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.

PS
Priya SharmaТехнічний рецензент

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.