Sallar Rabiei
Sallar Rabiei

Reputation: 782

why csv in python write only last row?

I have a CSV file, which contains the name (as the first column) and some numbers. I would like to write the mean of these number in a new CSV file.

Harry,5,7,3,15
David,3,9,4,20,9,1,8,16,0,5,2,4,7,2,1
Sara,19,10,19,6,8,14,3
Mohammad,0,5,20,14
Sallar,13,2,5,1,3,10,12,4,13,17,7,7
Yo,1,9
Alis,0,16,16,13,19,2,17,8

I use following code:

import csv
import statistics
from statistics import mean
import operator
from collections import OrderedDict
from operator import itemgetter
avgs = []
names =[]
key_sort = []
value_sort = []
dictlist = []
with open('grades.csv') as f:
    reader = csv.reader(f)
    for row in reader:
        name = row[0]
        these_grades = list()
        for grade in row[1:]:
            these_grades.append(int(grade))
        avgs.append(mean(these_grades))
        names.append(name)
        list_dict = dict(zip(names,avgs))#convet list to dictionary
    x = open ('out.csv' , 'w')
    x.write("%s , %f"  % (name ,mean(these_grades))) 

the output is :

Alis , 11.375000

As you see, the code only writes the last line, I expect results write like below:

Harry , 7.5
David , 6.066666666666666
Sara , 11.285714285714286
Mohammad , 9.75
Sallar , 7.833333333333333
Yo , 5.0
Alis , 11.375

Upvotes: 0

Views: 3420

Answers (5)

GPs
GPs

Reputation: 85

Writing only last row wrintingcsv

path = parsed[-2]  # this is the path element
    pathlist = path.split("/")
   # itm = len(pathlist)
    print(pathlist)
    with open('myfile.csv', 'w') as f:
        writer = csv.writer(f)
        for itm in pathlist:
            writer.writerow(re.findall(r'\d+', str(itm)))

and csv writes as

34235,1615316877939,1000043833

Upvotes: 0

Alderven
Alderven

Reputation: 8270

You can write to CSV line by line:

import csv
from statistics import mean


results = []
with open('grades.csv') as f:
    reader = csv.reader(f)
    for row in reader:
        results.append([row[0], mean([int(x) for x in row[1:]])])

results.sort(key=lambda x: x[1], reverse=True)
with open('out.csv', 'w', newline='\n') as f:
    writer = csv.writer(f)
    writer.writerows(results[:3])

Output:

Alis,11.375
Sara,11.285714285714286
Mohammad,9.75

Upvotes: 1

Tranqodile
Tranqodile

Reputation: 68

In this situation it is a good idea to write lines into the file as you calculate them within the loop. There were a few other things with your code that could be improved. I have simplified your code and tried to provide descriptions of what I modified:

# removed unused imports
# you do not need to import before using from
import csv
from statistics import mean

# For opening any files we often use "with" as it also closes them for us
# we can open our output file the same way
with open('grades.csv') as infile, open('out.csv', 'w') as outfile:
    # optionally you could change 'out.csv' to a csv.writer() but i left
    reader = csv.reader(infile)

    # if we write to the file on each loop we dont need to save the variables
    # it will also make things cleaner
    for row in reader:
        these_grades = [int(grade) for grade in row[1:]]
        # write a new line into the file directly after calculating
        outfile.write("%s , %f\n" % (row[0], mean(these_grades)))

output:

Harry , 7.500000
David , 6.066667
Sara , 11.285714
Mohammad , 9.750000
Sallar , 7.833333
Yo , 5.000000
Alis , 11.375000

Upvotes: 0

panda-34
panda-34

Reputation: 4209

If you use csv reader to read csv, why not use csv writer to write one? E.g like this:

import csv
from statistics import mean
with open('grades.csv', newline='') as f_in, open('out.csv', 'w', newline='') as f_out:
    csv.writer(f_out).writerows((name, mean(map(int, grades))) for name, *grades in csv.reader(f_in))

Upvotes: 0

Birdman
Birdman

Reputation: 1524

avgs = []
names = []
key_sort = []
value_sort = []
dictlist = []
with open('grades.csv') as f:
    reader = csv.reader(f)
    for row in reader:
        name = row[0]
        these_grades = list()
        for grade in row[1:]:
            these_grades.append(int(grade))
        avgs.append(mean(these_grades))
        names.append(name)
        list_dict = dict(zip(names, avgs))  # convet list to dictionary
    x = open('out.csv', 'w')
    #x.write("%s , %f" % (name, mean(these_grades))) #Why aren't we using list_dict? Didn't we already calculate the mean?

    for key in list_dict.keys():
        x.write("%s , %f\n" % (key, list_dict[key]))

I noticed that you weren't using your list_dict. I simply wrote for the key, value pair to your CSV file. Notice that I also commented out your original single write statement. Here we use a for loop to go through your entire dictionary.

Output in out.csv:

Harry , 7.500000
David , 6.066667
Sara , 11.285714
Mohammad , 9.750000
Sallar , 7.833333
Yo , 5.000000
Alis , 11.375000

Upvotes: 1

Related Questions