csv.reader
Give it anything that yields lines of text — an open file, a list of strings, io.StringIO — and iterate. Every field comes back as a str, and the file must be opened with newline=''.
Demo
import csv, io text = 'id,name\\n1,"Smith, John"'.replace('\\n', '\n') list(csv.reader(io.StringIO(text, newline=''), delimiter=',', quotechar='"'))
line_num is read after each row is produced, so a row whose quoted field spans two lines advances it by 2, and a blank line produces an empty list []. In strict: a quote that opens a field must be followed by the delimiter or the end of the line once it closes — "b"c is accepted as bc normally and is "',' expected after '"'" with strict=True. A quote in the middle of an unquoted field is just a character either way.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| csvfile | iterable of str | yes | Anything that yields lines: a file opened with newline='', a list of strings, io.StringIO. |
| dialect | str | Dialect | no ('excel') | A registered name ('excel', 'excel-tab', 'unix') or a Dialect class/instance. |
| fmtparams | keyword arguments | no | Override single settings: delimiter, quotechar, escapechar, doublequote, skipinitialspace, quoting, strict, lineterminator. |
Return value
_csv.reader — An iterator: each next() returns one row as a list of str (one row may span several input lines).
Common patterns
import csv with open('data.csv', newline='', encoding='utf-8') as f: for row in csv.reader(f): print(row)
import csv with open('data.csv', newline='', encoding='utf-8') as f: rows = csv.reader(f) header = next(rows) data = [row for row in rows]
import csv with open('data.csv', newline='', encoding='utf-8') as f: rows = csv.reader(f, strict=True) try: for row in rows: pass except csv.Error as e: print(f'line {rows.line_num}: {e}')
Examples
Pitfalls
import csv with open('p.csv', 'w', newline='') as f: f.write('a,b\r\n') with open('p.csv', 'rb') as f: rows = list(csv.reader(f))
import csv with open('p.csv', 'w', newline='') as f: f.write('a,b\r\n') with open('p.csv', newline='', encoding='utf-8') as f: rows = list(csv.reader(f)) rows
import csv with open('q.csv', 'w', newline='') as f: csv.writer(f).writerow(['line1\r\nline2']) with open('q.csv') as f: rows = list(csv.reader(f)) rows
import csv with open('q.csv', 'w', newline='') as f: csv.writer(f).writerow(['line1\r\nline2']) with open('q.csv', newline='') as f: rows = list(csv.reader(f)) rows
import csv rows = csv.reader(['a,b', 'c,d']) first = list(rows) second = list(rows) (len(first), len(second))
import csv rows = list(csv.reader(['a,b', 'c,d'])) (len(rows), len(rows))
When to use
- Row-by-row processing where columns are known by position
- Large files — the reader streams one row at a time
- Any delimiter: tabs, semicolons, pipes
- Columns by name → csv.DictReader
- Typed columns and analysis → convert yourself, or pandas.read_csv
- Fixed-width text → slicing, not csv
Notes
FAQ
Call next(reader) once before the loop: header = next(rows). Or use csv.DictReader, which reads the header for you and uses it as the dict keys.