0

so I have a list which has 6 dicts inside and I would like to write that to a csv file. I have tried a lot of ways to do it but i have been unsuccessful so far. when i try to write it as a list it give me an error when i try to write it as a dict it also give me an error. can anyone point me in the write direction please.

     r_vals=
     [{'distance':2.35, 'mpg': 3.215, 'power': 45.0},{'distance':214.3, 'mpg':   29.3,'power': 124.0},{'distance':2.35, 'mpg': 3.215, 'power': 45.0},...{'distance':0.35, 'mpg': 45.5, 'power': 156.0}]

or if there is easier way to get it as a dataframe I would like it to look like this

    distance   mpg       power
    2.35       3.215     45.0
    214.3      29.3      124.0
    .
    . 
    0.35       45.5      156

thank you!

2
  • Are you trying to get this into a CSV, and the dataframe part is just something you thought might help that goal, or are you trying to get this into a dataframe, and the CSV part is something you thought might help that goal? Commented Jan 22, 2014 at 22:49
  • @roippi: For a flat list of fixed-structure dicts, I think CSV makes more sense than JSON. (It makes that fixed structure explicit, avoids repetition, gives you a more human-readable/editable file, and lets you import it into Excel.) But it was definitely worth bringing up the option to show that CSV isn't the only file format in the world; you probably shouldn't have deleted the comment… Commented Jan 22, 2014 at 22:52

5 Answers 5

5

Have you looked into Pandas? http://pandas.pydata.org/

In pandas you can do this:

>>> r_vals
[{'distance': 2.35, 'power': 45.0, 'mpg': 3.215}, {'distance': 214.3, 'power': 124.0, 'mpg': 29.3}, {'distance': 2.35, 'power': 45.0, 'mpg': 3.215}, {'distance': 0.35, 'power': 156.0,'mpg': 45.5}]
>>> df = pandas.DataFrame(r_vals)
>>> df
   distance     mpg  power
0      2.35   3.215     45
1    214.30  29.300    124
2      2.35   3.215     45
3      0.35  45.500    156

and then you can do a:

df.to_csv("path.csv",index=False)

and you have saved your dictionary in both a dataframe in memory and a csv.

If you want to use just native python, then you can do something like this:

import csv
outfile = open("path.csv","w")
csv_writer = csv.write(outfile)
csv_writer.writerow(header)
header = r_vals[0].keys()
for row in r_vals:
  csv_writer.writerow(str([row[col_name]) for col_name in header])
outfile.close()
Sign up to request clarification or add additional context in comments.

2 Comments

If his main goal is to create and work with a data frame, the first half of this answer is obviously a much better way to do it than creating a CSV file and trying to process it.
But for the second half… you're going through a lot of extra work to turn each dict into a sequence so you can use writer instead of DictWriter… Also, you don't need to call str with either writer or DictWriter.
3

"create a csv file from a list with dictionary elements in python" is exactly what csv.DictWriter does:

with open('output.csv', 'w') as f:
    csv.DictWriter(f, fieldnames=rvals[0].keys()).writerows(rvals)

(If your ultimate goal is to get some kind of data frame object, and you're just creating a CSV file because you think it's the best way to do that… then you don't have to; see Ryan G's answer for how easy pandas makes this.)

After this:

$ cat output.csv
3.215,45.0,2.35
29.3,124.0,214.3
3.215,45.0,2.35
45.5,156.0,0.35

Of course you probably want it to include the headers and/or put the columns in some particular order rather than whatever order the dict happens to have. (You don't need to do both, but if you don't do either one or the other, the CSV isn't very useful, because you'll have no idea which column means what…) Here's both:

with open('output.csv', 'w') as f:
    w = csv.DictWriter(f, fieldnames='distance mpg power'.split())
    w.writeheader()
    w.writerows(rvals)

Output:

distance,mpg,power
2.35,3.215,45.0
214.3,29.3,124.0
2.35,3.215,45.0
0.35,45.5,156.0

If you want a variation on the default CSV dialect, see Dialects and Formatting Parameters. To get exactly your desired output, just add , delimiter='\t' to the DictWriter constructor.

1 Comment

@user3225439: What did you try? What didn't work? The output in my examples all come from running this exact code against your exact rvals but with the ... removed to make it a valid list.
0

use tabulate

r_vals=[[2.35,3.215,45.0],[214.3,29.3,124.0],[2.35, 3.215,45.0],[0.35,45.5,156.0]]

 print tabulate.tabulate(r_vals, headers=["distance","mpg", "power"])

  distance     mpg    power
----------  ------  -------
      2.35   3.215       45
    214.3   29.3        124
      2.35   3.215       45
      0.35  45.5        156

1 Comment

If you're going to suggest a third-party library, you should probably include a link, describe what it does (including what makes it better than stdlib solutions), or something.
0

You can use string formatting to do what you want:

with open(target, 'w') as f:
    f.write("distance\tmpg\tpower\n") # header
    for d in r_vals:
        f.write"{0[distance]:.2f}\t{0[mpg]:.3f}\t{0[power]:.1f}\n".format(d))

Here the format specification is 0 for the first argument to format, [key] to select the appropriate value, then .nf to give n decimal places.

Comments

0

http://docs.python.org/2/library/csv.html#csv.DictWriter should do that, it will also write a header row based on the column order you provide.

with open('/home/dnfehren/windesk/test.csv','wb') as fl:
    fc = csv.DictWriter(fl, ['distance','mpg','power'])

    for rvalnum, rval in enumerate(rvals):
        if rvalnum == 0:
            fc.writeheader()
            fc.writerow(rval)
        else:
            fc.writerow(rval)

2 Comments

Why move writeheader into the loop (which then requires you to add enumerate and a check for 0), when you can just call it before the loop (which then allows you to eliminate the loop and use writerows instead)?
thanks! good point - I usually add a loop counter out of habit as there could be other things that I want to track by where they occur in a list or file

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.