1

I have a list which contains strings integers and floats. I want to convert it into a string and save it to file (CSV format) - I dont want to convert every field manually - but I would also prefer not to use the CSV parsing module as it is too heavyweight for a quick and dirty script which has a format that never changes.

What is the pythonic way of doing this? The "".join() "pattern" fails because the list contains non string members.

oompahloompah
  • 9,087
  • 19
  • 62
  • 90

4 Answers4

6

I would also prefer not to use the CSV parsing module as it is too heavyweight for a quick and dirty script

Really, what's the cost? A few milliseconds of runtime, or a few minutes of development time?

which has a format that never changes

That's irrelevant. You have data that requires escaping, quoting, formatting, etc. Might the data itself change in the future, even if the format doesn't? You will only end up re-inventing the workarounds in the CSV module anyway, but probably not as comprehensively.

import csv

data_row = [1, 2.0, "three", "pi,plus,one"]

# Assuming Python 2.x
# ...in Python 3 use text mode: open("...", 'w', newline='')
with open("datafile.csv", 'wb') as datafile:
    datawriter = csv.writer(datafile)
    datawriter.writerow(data_row)

Using the join approach would be one line shorter — and that's assuming you don't need to roll-your-own escaping, etc.

(See the CSV writer docs and this answer for the reason behind the file open mode.)

Community
  • 1
  • 1
detly
  • 29,332
  • 18
  • 93
  • 152
  • 1
    -1 omg rubber stamp comment time yet again """csv files should be opened in binary mode ('rb', 'wb', etc) in Python 2.x; in 3.x: text mode (the default) and with `newline=''` – John Machin Mar 24 '11 at 02:10
  • @John Machin - fair enough. I'll edit. Do you have a reference for that, because I use the CSV module a fair bit and haven't seen that info. – detly Mar 24 '11 at 02:13
  • @detly: 2.7 docs; 3.2.0 docs don't mention writer but see http://bugs.python.org/issue7198 – John Machin Mar 24 '11 at 02:24
  • @John Machin - Thanks, by the way — that would have bitten me in the arse in a few days time... – detly Mar 24 '11 at 02:33
  • 1
    @detly: That's serious ... or did you mean "on" the fundament rather than "in"? – John Machin Mar 24 '11 at 02:45
  • @John Machin - depends on how high my code can jump, I guess. – detly Mar 24 '11 at 03:05
4

Use a genex.

','.join(str(x) for x in L)
Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • 2
    What if the strings happen to contain commas, double quotes, or returns? – btilly Mar 24 '11 at 01:51
  • 1
    @btilly: Then the asker has a problem which he already knows how to solve. – Ignacio Vazquez-Abrams Mar 24 '11 at 01:53
  • @Ignacio: If the asker knew how to solve those problems, he wouldn't be asking the question. – John Machin Mar 24 '11 at 02:15
  • @btilly Read the question: "a list which contains strings integers and floats." Given those requirements, Ignacio's answer fits perfectly. – Steven Rumbalski Mar 24 '11 at 03:28
  • @Ignacio I would prefer a newline separator to a comma. Although mentions csv is mentioned, a reread of the question shows that commas are not a requirement. With newlines, the file will be more readable if he needs to open it in a text editor. – Steven Rumbalski Mar 24 '11 at 03:31
  • @btilly Darn, i didn't read the question -- I missed the word strings in my own quote. But hey, maybe i can get away with blaming the lack of commas in his sentence. – Steven Rumbalski Mar 24 '11 at 03:35
  • @Ignacio Double darn. I *really* didn't read the question as he really does want csv. What was I thinking? – Steven Rumbalski Mar 24 '11 at 03:39
0

If you don't want to convert the fields manually, either give the job to some users or write some code. If you don't want to use the "heavyweight" csv module, you'll need code like this to handle wrinkles in strings:

def csv_escape(s):
    if '"' in s:
        return '"' + s.replace('"', '""') + '"'
    if any(c in s for c in ",\r\n"):
        return '"' + s + '"'
    return s
John Machin
  • 81,303
  • 11
  • 141
  • 189
0

How about this?

import json
json.dumps(mylist)

It's not exactly traditional CSV format, but since you don't want to use the CSV module, I gather you're not too concerned about that.

ʇsәɹoɈ
  • 22,757
  • 7
  • 55
  • 61