How to Write a Dictionary to a File in Python

To write a dictionary to a file in Python, pick a format first: json.dump(d, f) for data other programs read, a key: value line per item for plain text, csv.DictWriter for a list of dicts, or pickle.dump() for Python-only data:

with open("prices.txt", "w", encoding="utf-8") as f:
    for item, price in prices.items():
        f.write(f"{item}: {price:.2f}\n")

The real question is what you get back when you read the file, so every example below loads the data again; I ran them all on Python 3.12.5.

You’ll see plain text lines, repr with ast.literal_eval, JSON, CSV for several records, pickle for Python objects, and a table of what each format keeps.

Write a dictionary to a text file, one key per line

For a file people will read or edit by hand, write one line per key. Reading it back means splitting each line and converting the value yourself:

from pathlib import Path

prices = {"Coffee beans": 14.99, "Mug": 9.50, "Filters": 4.25}

with open("prices.txt", "w", encoding="utf-8") as f:
    for item, price in prices.items():
        f.write(f"{item}: {price:.2f}\n")

print(Path("prices.txt").read_text(encoding="utf-8"))

loaded = {}
for line in open("prices.txt", encoding="utf-8"):
    item, price = line.rstrip("\n").split(": ")
    loaded[item] = float(price)
print(loaded == prices, loaded)

Output:

Coffee beans: 14.99
Mug: 9.50
Filters: 4.25

True {'Coffee beans': 14.99, 'Mug': 9.5, 'Filters': 4.25}
Command Prompt output of Python writing a price dictionary to a text file as key: value lines and reading it back
Three items print as key: value lines with two-decimal prices, and parsing them back gives a dictionary equal to the original.

Pick a separator that never appears in your keys. For other ways to save text, see writing a string to a file in Python.

Write a dictionary with repr() and read it with ast.literal_eval()

repr() writes the dict exactly as Python would print it, tuples and sets included. ast.literal_eval() reads it back safely, because it only accepts literals:

import ast
from pathlib import Path

store = {"id": 12, "city": "Austin", "open": True, "hours": (7, 19), "tags": {"drive-thru"}}

Path("store.txt").write_text(repr(store), encoding="utf-8")
print(Path("store.txt").read_text(encoding="utf-8"))

back = ast.literal_eval(Path("store.txt").read_text(encoding="utf-8"))
print(back == store, type(back["hours"]).__name__, type(back["tags"]).__name__)

try:
    ast.literal_eval("__import__('os').getcwd()")      # code, not data
except ValueError as err:
    print("ValueError:", err)

Output:

{'id': 12, 'city': 'Austin', 'open': True, 'hours': (7, 19), 'tags': {'drive-thru'}}
True tuple set
ValueError: malformed node or string on line 1: <ast.Call object at 0x000001F24EFED890>
Command Prompt output of Python saving a dict with repr and loading it with ast.literal_eval, which rejects code
The dict round-trips with its tuple and set intact, while literal_eval refuses a string that would run code.

Never use eval() on a file: it would run that code. This format only works for Python, so for anything shared, use JSON. Turning a dict into a string first is covered in converting a dictionary to JSON in Python.

Write a dictionary to a JSON file

JSON is the right default for settings, API data and anything another language reads. The catch is that only JSON types survive:

import json
from pathlib import Path

store = {"id": 12, "city": "Austin", "open": True, "hours": (7, 19)}
Path("store.json").write_text(json.dumps(store, indent=2), encoding="utf-8")
back = json.loads(Path("store.json").read_text(encoding="utf-8"))
print(back)
print(back == store, "<- the tuple came back as a list")

Output:

{'id': 12, 'city': 'Austin', 'open': True, 'hours': [7, 19]}
False <- the tuple came back as a list

The tuple (7, 19) comes back as a list, so the loaded dict isn’t equal to the original. Indenting, dates and safe writes are all in my guide to writing JSON data to a file in Python.

Write a list of dictionaries to a CSV file

When you have many records with the same keys, CSV opens straight in Excel. csv.DictWriter uses the keys as column headers:

import csv
from pathlib import Path

orders = [
    {"id": 1001, "customer": "Emily Carter", "state": "TX", "total": 129.99},
    {"id": 1002, "customer": "James Wilson", "state": "CO", "total": 54.50},
]

with open("orders.csv", "w", newline="", encoding="utf-8") as f:
    writer = csv.DictWriter(f, fieldnames=orders[0].keys())
    writer.writeheader()
    writer.writerows(orders)

print(Path("orders.csv").read_text(encoding="utf-8"))
rows = list(csv.DictReader(open("orders.csv", encoding="utf-8")))
print(rows[0], "<- every value is a string again")

Output:

id,customer,state,total
1001,Emily Carter,TX,129.99
1002,James Wilson,CO,54.5

{'id': '1001', 'customer': 'Emily Carter', 'state': 'TX', 'total': '129.99'} <- every value is a string again
Command Prompt output of Python csv.DictWriter writing a list of order dictionaries to CSV and reading them back as strings
The CSV has a header row and one line per order; reading it back with DictReader gives every value as a string.

Pass newline="" when opening, or Windows adds blank lines between rows. More CSV options are in writing a Python dictionary to CSV.

How do I save a dictionary with dates and Decimals?

pickle stores any Python object, so dates, Decimals and sets come back exactly. The file is binary and Python-only:

import pickle
from datetime import date
from decimal import Decimal

order = {"id": 1003, "placed": date(2026, 10, 8), "total": Decimal("89.10"), "items": {"Mug", "Beans"}}

with open("order.pkl", "wb") as f:
    pickle.dump(order, f)

with open("order.pkl", "rb") as f:
    back = pickle.load(f)

print(back == order, back["placed"], repr(back["total"]))
print(open("order.pkl", "rb").read(20), "...")

Output:

True 2026-10-08 Decimal('89.10')
b'\x80\x04\x95y\x00\x00\x00\x00\x00\x00\x00}\x94(\x8c\x02id\x94M' ...
Command Prompt output of Python pickle.dump and pickle.load round-tripping a dictionary with a date, Decimal and set
The loaded order equals the original, the date and Decimal keep their types, and the file starts with binary bytes.

Only unpickle files you created yourself: loading a pickle can run code. For bytes in general, see writing bytes to a file in Python.

Which file format should you use for a dictionary?

FormatWrite withComes back asUse for
Text linesf.write(f"{k}: {v}")Strings you parseSimple hand-edited lists
reprrepr(d) + ast.literal_evalSame types (literals)Quick Python-only saves
JSONjson.dump(d, f)dict, list, str, int, float, bool, NoneSharing, config, APIs
CSVcsv.DictWriterStringsMany records, spreadsheets
picklepickle.dump(d, f)Exactly the same objectsTrusted Python-only caches

Once the data is saved, these will help you work with it:

Frequently asked questions

How do I write a dictionary to a file in Python?

Use json.dump(d, f) for most cases. For plain text, write one key: value line per item.

How do I read a dictionary back from a text file?

If you wrote it with repr(), use ast.literal_eval(). Never use eval().

Why is my tuple a list after loading JSON?

JSON has no tuple type, so tuples are written as arrays and load as lists.

How do I write a list of dictionaries to CSV?

Use csv.DictWriter(f, fieldnames=rows[0].keys()), then writeheader() and writerows(rows).

Is pickle safe for saving dictionaries?

Only for files you created. Loading an untrusted pickle can execute code.

Where is ast.literal_eval documented?

See ast.literal_eval() in the Python docs.