writer() and writerow()
Two lines of new code, and one of them only runs once. csv.writer(f) wraps the open file; then writerow() takes a list and puts it in the file as one line — commas and all, which is three jobs you no longer do by hand.
1csv.writer() — wrapping the file
w = csv.writer(file)One argument — the file open() gave you, in 'w' or 'a'. What comes back is the writer.
The name w is just a variable. Call it writer, csvwriter, or anything else — the board's own papers use several. What matters is that the object it holds is the thing with the methods on it.
'w' is empty before it and empty after it.2writerow() — one list, one line
w.writerow(a list)Each item of the list becomes one value in the row. Call it again for the next row.
import csv
f = open('marks.csv', 'w', newline='')
w = csv.writer(f)
w.writerow(['Roll', 'Name', 'Marks'])
w.writerow([1, 'Ravi', 78])
w.writerow([2, 'Meera', 91])
w.writerow([3, 'Amit', 65])
f.close()
print('marks.csv written')marks.csv written
And here is the file it produced, opened in Notepad:
Roll,Name,Marks
1,Ravi,78
2,Meera,91
3,Amit,65w.writerow(['Roll', 'Name', 'Marks'])The header row is nothing special — just the first writerow(). The csv module has no idea it is a header, and neither will the reader.
w.writerow([1, 'Ravi', 78])1 and 78 are numbers and went straight in. write() would have refused them; writerow() converts them for you.
1,Ravi,78Two commas for three values, and a line ending you never typed. That is the work the module took over.
3Watch the list become a line
Pick a row and watch what writerow() writes — then what reader() gives back when the file is read again.
w.writerow(['Roll', 'Name', 'Marks'])Roll,Name,Marks['Roll', 'Name', 'Marks']Two commas for three values — one between each pair, none at the end.
4The same file, written by hand
Worth comparing directly, because the exam sometimes asks for the difference:
| f.write() | w.writerow() | |
|---|---|---|
| What it takes | one string | a list of values |
| Numbers | refused — TypeError, you need str() | accepted as they are |
| Separators | you type every comma yourself | put in for you |
| Line ending | you add '\n' yourself | added for you |
| A comma inside a value | breaks the file silently | the value is quoted automatically |
| Gives back | the number of characters written | the number of characters written |
import csv
# by hand — three things to remember on every row
f = open('a.csv', 'w')
f.write('Ravi' + ',' + str(78) + '\n')
f.close()
# with the module — none of them
f = open('b.csv', 'w', newline='')
w = csv.writer(f)
w.writerow(['Ravi', 78])
f.close()
print(open('a.csv', 'rb').read())
print(open('b.csv', 'rb').read())b'Ravi,78\n' b'Ravi,78\r\n'
Same values, same commas — and one difference at the very end. The line you wrote by hand ends in \n, because that is what you typed. The writer's line ends in \r\n, because that is the ending the CSV standard asks for and the writer always uses it.
\r\n is two characters, not one. Nothing goes wrong here — every program on earth reads that file correctly. But it is the whole reason newline='' exists, and the lesson three pages from now is about what happens when you leave it out.5Rows come from a loop, not from ten typed lines
Real programs do not know their rows in advance. The data sits in a list, and writerow() goes inside a for:
w.writerow(['Roll', 'Name', 'Marks']) inside the loop by mistake and you get a header line before every single record. It is written once, so it sits above the loop.6What writerow() gives back
It returns the number of characters it wrote — the same thing write() returns, and just as ignorable:
import csv
f = open('t.csv', 'w', newline='')
w = csv.writer(f)
print(w.writerow(['Ravi', 78]))
f.close()9
Nine, because the line is Ravi,78 followed by the two characters of the line ending. Nobody uses this value. The point of the call is the change it makes to the file.
7Four mistakes worth knowing in advance
w.writerow('Ravi')A string, not a list. Python takes each letter as a value and writes R,a,v,i. No error — just a wrong file.
csv.writerow(['Ravi', 78], f)writerow belongs to the writer object, not to the module. AttributeError: module 'csv' has no attribute 'writerow'.
Forgetting f.close()The rows may still be in the buffer. Open the file and it looks empty or half written.
Opening in 'w' to add a record'w' empties the file first. Every record already in it is gone before writerow() runs once.
import csv
f = open('trap.csv', 'w', newline='')
w = csv.writer(f)
w.writerow('Ravi')
f.close()
print(open('trap.csv').read())R,a,v,i
writerow() takes a list of values. One value still needs its square brackets: w.writerow(['Ravi']). Without them Python looks inside the string and finds four characters, which are four values as far as it is concerned.8Recap
Wraps the open file. Runs once, writes nothing by itself.
Writes one row. Each item of the list becomes one value.
The three jobs write() left to you — the separator, the line ending and str() — are all gone.
78 goes in as 78. It comes back as '78', but that is the reader's lesson.
One writerow() above the loop. The module gives it no special status.
writerow('Ravi') writes R,a,v,i. writerow(['Ravi']) writes Ravi.
- 1
Write a CSV of five of your subjects and their marks, with a header row.
Hint · One writerow() for the header, then a loop for the rest.
- 2
Run
w.writerow('Ravi')and open the file.Hint · R,a,v,i — and no error at all, which is the danger.
- 3
Write a row with a name that contains a comma, and open the file in Notepad.
Hint · Double quotes you never typed. The writer put them there.
- 4
Write the header inside the loop on purpose and look at the result.
Hint · Four headers for three records.
What does w.writerow(['Ravi', 78]) put in the file?
Do numbers need str() before writerow()?
w.writerow('Meera') writes what into the file?
Where should the header's writerow() go when the records are written in a loop?