How does `.writeheader()` know the fields to use?

Just want to clarify a few things on this one…?

From the model code explanation:

Now that we’ve instantiated our CSV file writer, we can start adding lines to the file itself! First we want the headers, so we call .writeheader() on the writer object.

This writes all the fields passed to fieldnames as the first row in our file.

^^ Q: This is done without passing any arguments in ‘.writeheader()’?

Then we iterate through our big_list of data. Each item in big_list is a dictionary with each field in fields as the keys. We call output_writer.writerow() with the item dictionaries which writes each line to the CSV file.

^^Q: .writerow() automatically knows that these will be dictionary values and pulles the value data for each key in the list? access_log comes preformatted as a list with dictionary elements, most CSV data won’t come in this format, no?

import csv 

with open('logger.csv','w') as logger_csv:
  log_writer = csv.DictWriter(logger_csv, fieldnames = fields)
  
  log_writer.writeheader()
  for item in access_log:
    log_writer.writerow(item)

TIA!

1 Like

The argument is passed when the DictWriter() object is instantiated: look at the arguments for DictWriter():

 output_writer = csv.DictWriter(output_csv, fieldnames=fields)

writeheader() is a method of the class DictWriter, and it (writeheader) looks for the list of fields in the fieldnames parameter passed to DictWriter().

Yes, precisely. If you do not have a dictionary to start with, use a different tool (possibly csv.writer).

That is what DictWriter does. It works with data formatted in dictionary form. From the docs, the action of DictWriter is to

Create an object which operates like a regular writer but maps dictionaries onto output rows.

3 Likes

We want to add the columns’ headers to the instance of csv.Dictwriter. In the code below, why should we launch “output_writer.writeheader()”, if earlier we already “showed”, that we want to add the headers: “output_writer = csv.DictWriter(output_csv, fieldnames=fields”?

with open('output.csv', 'w') as output_csv:
  fields = ['name', 'userid', 'is_admin']
  output_writer = csv.DictWriter(output_csv, fieldnames=fields)

  output_writer.writeheader()
  for item in big_list:
    output_writer.writerow(item)

Lesson’ link: https://www.codecademy.com/courses/learn-python-3/lessons/learn-python-files/exercises/writing-a-csv-file

It allows for the possibility that you might not want to print the fieldnames as part of your output file,

1 Like

Thank you. But if I use this expression inside ‘with’ (while the file is opened to changes), I can’t imagine with what another purpose but ‘write’ I can use it.

It would be much easier if it took 3 parameters(output_file, headers, rows).

1 Like

Can you not imagine that you might want to write to a “data only” .csv file having no headers?

1 Like

Just in case anyone has the same problem I had:

I didn’t see that the list “fields” had already been established at the top and I made my own. For some reason that made it so that I always failed the last step, even though I did everything right (I even opened the logger csv in read only mode and printed it to check that I had written to the file correctly and it was still failing me). I had to delete my “fields” list in order to pass.

I’m guessing that because fields = [‘time’, ‘address’, ‘limit’] already exists within the code, the algorithm for this step expects the output fields to be in the order: ‘time’, ‘address’, ‘limit’.

Mimicking the example and listing the fields within the ‘open’ block in the same order that they appear in as keys within the dictionaries causes a fail.

How do we know when to use .DictWriter() vs .write() I was going through the hacking project where I had to write into a CSV file and I thought we had to use .DictWriter() instead of just using .write().

I was under the assumption that CSV files needed .DictWriter() while regular txt files used .write()