Use Python’s built-in csv module: pass a list of row sequences to csv.writer, or use csv.DictWriter when each record is a dictionary with named fields. Open the file with newline='' so the CSV module can handle line endings correctly.
Write a list of rows to a CSV file
Each inner iterable represents one CSV record. If the first row contains column labels, the writer outputs it like any other row; it does not add or infer a header.
import csv
rows = [
["name", "age"],
["Ada", 36],
["Linus", 55],
]
with open("people.csv", "w", newline="") as csvfile:
writer = csv.writer(csvfile)
writer.writerows(rows)
Use writer.writerow(row) to write one record, or writer.writerows(rows) to write an iterable of records. The file is opened in write mode, so an existing file with that name is overwritten. For the writer API and its options, see the Python 3.14.8 csv documentation.
Write a table stored as dictionaries
Use csv.DictWriter when each row maps field names to values. Supply fieldnames to define the CSV columns and their order; call writeheader() if you want those names written as the first row.
Recommended Free Tools
#1 Best Overall
import csv
rows = [
{"name": "Ada", "age": 36},
{"name": "Linus", "age": 55},
]
with open("people.csv", "w", newline="") as csvfile:
fieldnames = ["name", "age"]
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
writer.writerows(rows)
By default, a dictionary key absent from fieldnames raises ValueError. A field listed in fieldnames but absent from a row is filled with restval, which defaults to an empty string. Set extrasaction='ignore' only if you deliberately want to discard keys that are not listed.
When your data is stored as separate columns
The CSV writer consumes rows, not independent column lists. Arrange values from corresponding positions into rows before passing them to writerows. For equal-length lists, zip pairs the first values together, then the second values, and so on:
Rank #2
import csv
names = ["Ada", "Linus"]
ages = [36, 55]
rows = zip(names, ages)
with open("people.csv", "w", newline="") as csvfile:
writer = csv.writer(csvfile)
writer.writerow(["name", "age"])
writer.writerows(rows)
If the columns have different lengths, decide how to handle the unmatched values before writing. In particular, ordinary zip stops when the shortest input is exhausted, so longer columns can lose trailing values. Choose a fill value or another explicit alignment rule if you need to preserve them.
Quick Recap
Best Value
Choose the writer that matches your data
| Writer | Input shape | Column order | Header | Field handling |
|---|---|---|---|---|
csv.writer |
Ordered row sequences, such as lists or tuples | The order in each row determines the columns | Write a header row yourself if wanted | Values are written positionally |
csv.DictWriter |
Mappings such as dictionaries | Declared by the required fieldnames sequence |
Call writeheader() if wanted |
Extra keys raise ValueError by default; missing fields use restval |
CSV details that affect the output
- Open with
newline=''. This is the documented way to open text files used with the CSV writer; it lets the module manage newline handling. - Let the writer quote fields. Under the default Excel dialect, fields containing commas, quotes, or newlines are quoted as needed. Do not manually join values with commas for general data; the writer applies delimiter and quoting rules.
- Account for value conversion. Non-string values are converted with
str().Noneis written as an empty string, so that distinction cannot be recovered from the CSV alone unless you define an additional convention. - Do not expect Python types to round-trip automatically. CSV is text serialization, and the standard reader returns strings by default. Convert values back to numbers, dates, or other types explicitly when reading if your application requires it.
- Configure a dialect when needed. The default Excel dialect uses commas, but applications may expect different delimiters or quoting conventions. Set the dialect or relevant formatting parameters to match the receiving application.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




