[Tutor] write dictionary to file

Walter Prins wprins at gmail.com
Fri Jun 20 18:48:57 CEST 2014


Hi,

You've had a very good reply from Mark already however I want to add
to it and further clarify what he pointed out (why exactly *are* you
getting the tuple error after all?), also I've updated the prior
example to help explain, see below:

On 20 June 2014 15:11, Ian D <duxbuz at hotmail.com> wrote:
>
> import csv
>
> csvfile= open('StudentListToSort.csv', newline='')
> spamreader = csv.reader(csvfile,delimiter=',',quotechar='|')
> outfile = open('outfile.csv','w')
>
> for row in spamreader:
>
>     if row[4] == '6':
>         print("".join([row[0],'@email.com']),row[1])
>         email = "".join([row[0],'@email.com'])
>         output = email,row[1]
>         outfile.write(output)

... Note that you're writing using the ///plain file object itself///,
which indeed would expect a simple string to write.  Obviously a plain
file object, such as outfile, doesn't know by itself how to write a
tuple of objects, that's more the CSV object's job, hence you get the
error you're getting.

Instead you want to be writing using a CSV object instead, as you
originally indeed were doing.  I suspect you simply forgot to use the
CSV writer and accidentally tried to write the output tuple directly
with the file object? So I'm with Mark -- less haste, more speed.  :)

Finally I've updated the previous example to work with Python 3 and
added some comments, so you should be able to run it without problems.
Hopefully this should be enough to get you going.  :)

# -*- coding: utf-8 -*-

import csv

def create_demo_file(csv_demo_filename):
    csvfile=open(csv_demo_filename, 'w',  newline='')
    #Here we instantiate a CSV writer that accepts plain list like objects for
    #writing, and then use it to write some demo data by passing it a list of
    #tuples.
    csvwriter = csv.writer(csvfile, quoting=csv.QUOTE_MINIMAL)
    csvwriter.writerow(['user','first','last','password','year'])
    csvwriter.writerows([
        (1, 'john', 'smith', 'LKJ£$_£(*$£', 35),
        (2, 'joe',  'bloggs','5^££J"HLLDD', 40),
        (3, 'alice','jones', '^%!*&^%1681', 43),
        (4, 'bob',  'white', '!&££JHLKJ*F', 28),
        ])
    csvfile.close()


def add_email_to_csv(csv_input_filename, csv_output_filename):
    csvfile= open(csv_input_filename)
    csvoutput = open(csv_output_filename, 'w+', newline='')
    #Here we instantiate a CSV reader that gives us each row as a dict object
    #(as opposed to one which simply gives the values as a plain list)
    csvreader = csv.DictReader(csvfile)

    fields = ['user','first','last','password','year', 'email']
    #Here we instantiate a csv writer that accepts dicts for writing.
    #We pass it the formal field list as part of the constructor params
    #and ask it to write the header line as a first step.
    csvwriter = csv.DictWriter(csvoutput,fieldnames=fields)
    csvwriter.writeheader()

    #Step through each row dict object...
    for row in csvreader:
        if row['year'] in ('43', '40'):
            #Again: The row is a dict, containing an entry for every
column in the table.
            #We cheat, and simply add a new column to this existing dict,
            # by simply assigning to the dict as normal. Then we ask
the CSV output
            # writer to write this (now modified) dict as the row to
the output file:
            row['email'] = row['user']+'@email.com'
            csvwriter.writerow(row)
    csvoutput.close()


###
create_demo_file('StudentListToSort.csv')
print('Demo input file created contents:')
print(open('StudentListToSort.csv', 'r').read() )

add_email_to_csv('StudentListToSort.csv', 'output.csv')
print('Demo output file created contents:')
print(open('output.csv', 'r').read())


HTH,

Walter


More information about the Tutor mailing list