HOWTO · Python

How to Read a CSV With Its Header in Python

Learn how to read a CSV with its header in Python.

On this page

Python’s standard-library csv module can read a comma-separated file row by row. A CSV file often stores column names in its first row, followed by the records. The examples here assume that layout; csv.reader itself does not automatically treat the first row as a header. It returns an iterable of rows, with each row represented as a list of strings.

The examples create a small input file themselves, so you can run each one without downloading a companion file. For a real file, replace the temporary file setup with its path and open it using newline="" and an encoding appropriate for that file. The sample email CSV file is another input you can inspect. The output after each example shows its observed result.

Read a CSV file with its header in Python

Pass an open text file to csv.reader and iterate over the result. The loop includes every row, so the first printed list is the column-name row. This is useful when you want to inspect the raw records before handling the header separately.

Run this example:

import csv
import tempfile

with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8", newline="", delete=False) as source:
    source.write("name,team\nAda,Research\nLin,Design\n")
    path = source.name

with open(path, encoding="utf-8", newline="") as source:
    rows = csv.reader(source)
    for row in rows:
        print(row)
['name', 'team']
['Ada', 'Research']
['Lin', 'Design']

The reader parses fields according to CSV quoting rules; splitting each line manually on commas can give incorrect results when a field contains a comma inside quotes. Iterating through the file reads it in one pass, so the time grows linearly with the input size. If the file is large, this pattern does not need to hold all rows in memory at once.

Extract the header and process rows separately

Call the built-in next() function on the reader to consume its first row and store it as the header. The reader then continues at the following row, allowing the loop to handle only data records. This separates column names from values without loading the whole file into a list.

Run this example:

import csv
import tempfile

with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8", newline="", delete=False) as source:
    source.write("name,team\nAda,Research\nLin,Design\n")
    path = source.name

with open(path, encoding="utf-8", newline="") as source:
    rows = csv.reader(source)
    header = next(rows)
    print("Header:", ", ".join(header))
    for row in rows:
        print(dict(zip(header, row)))
Header: name, team
{'name': 'Ada', 'team': 'Research'}
{'name': 'Lin', 'team': 'Design'}

Here zip pairs each column name with the corresponding field, and dict makes those pairs accessible by name. This assumes the file has a header row and that each record has fields in the same order. For files that may contain no rows, check for a first row before using it as a header; otherwise next() has no row to return.

Read a CSV with a different delimiter

A comma is the default separator. For a file that uses semicolons, pass the delimiter argument to csv.reader; use the character that actually separates fields in your input. The same reader behavior applies, but header handling remains explicit: by convention, the first row contains the header; csv.reader does not interpret it as a header, so this example consumes it with next() before printing records.

Run this example:

import csv
import tempfile

with tempfile.NamedTemporaryFile(mode="w", encoding="utf-8", newline="", delete=False) as source:
    source.write("name;team\nAda;Research\nLin;Design\n")
    path = source.name

with open(path, encoding="utf-8", newline="") as source:
    rows = csv.reader(source, delimiter=";")
    header = next(rows)
    print("Header:", ", ".join(header))
    for row in rows:
        print(", ".join(row))
Header: name, team
Ada, Research
Lin, Design

For other formats, set delimiter to the separator used by the file, such as a tab character. Keep newline="" when opening files for the CSV module, and choose an encoding that matches the source data. If the rows contain quoted fields or embedded newlines, let csv.reader parse them instead of preprocessing lines yourself.