9

I am trying to create a european-formatted csv in python. I already set the separator to a semicolon

writer = csv.writer(response, delimiter=';', quoting=csv.QUOTE_ALL)

However, this still uses dot . as the decimal separator. What's the correct way to make it use a comma, as is correct for my locale? I can't seem to find any way to set it in the docs. (I am using, and would prefer to stick to, the built-in csv module)

maniexx
  • 534
  • 1
  • 9
  • 24
  • What the about the decimal separator from the data source ? – Ali SAID OMAR Oct 03 '16 at 14:08
  • There's some discussion about this in this link - it may be useful: http://stackoverflow.com/questions/7751157/python-csv-list-separator-based-on-regional-settings – emmalg Oct 03 '16 at 14:10
  • @AliSAIDOMAR what? I have some python floats, so they don't really have a decimal separator assigned to them, they are numbers. But I don't think I understand your question. – maniexx Oct 03 '16 at 14:11
  • @emmalg unfortunately this only seems to concern CSV separators, not decimal separators. – maniexx Oct 03 '16 at 14:14
  • @martineau Please take a look at my edit, I don't think this question is a duplicate of the one you linked. – maniexx Oct 03 '16 at 15:41
  • 2
    @maniexx: Yes, the other question is about reading and yours is about writing. However that is a minor difference, since the solution in either case is to replace the decimal mark character with something else, `'.'` with `','` or vice-versa in the duplicate. The answers to the other question are slightly better, IMO, because they also deal with potential issues when dealing with large numbers with a mixture of the two character in them, as well as describing code that does things in a locale-aware way. – martineau Oct 03 '16 at 15:57
  • 2
    As stated by OP, **this got marked as a duplicate, but the linked question concerns reading and not writing**. – Basj Oct 30 '18 at 12:21
  • 1
    Although the solution might be similar, the question is *not* a duplicate! – Michel de Ruiter Dec 23 '19 at 09:27

1 Answers1

10

A little bit hacky way, but it's the best I can think of: convert floats to strings and replace . with ,:

def localize_floats(row):
    return [
        str(el).replace('.', ',') if isinstance(el, float) else el 
        for el in row
    ]

for row in rows:
    writer.writerow(localize_floats(row))

If you want better localization handling, I suggest you convert all numbers using babel.numbers package.

skovorodkin
  • 6,588
  • 1
  • 31
  • 27
  • Won't they be encoded as strings in the csv? IE quoted and interpreted as strings by other software? – maniexx Oct 03 '16 at 14:43
  • They won't be quoted as you set `;` as delimiter. – skovorodkin Oct 03 '16 at 14:44
  • I don't know how other software will handle such format though. IMO it's easier to output numbers as is and then localize them when you really need that (e.g. in UI). – skovorodkin Oct 03 '16 at 14:46
  • Yeah, but the csv is going to be read in excel and such. So that's sadly not an option. And an XLS(x) or some other format which is actually a format is not allowed either. – maniexx Oct 03 '16 at 14:48
  • 1
    Got it. Then just replace dots with commas or use Babel's `format_number` function. It'll work. – skovorodkin Oct 03 '16 at 14:51
  • I tested your answer, it works for me. Thanks a lot, and I'll be sure to checkout babel if it turns out I need localization somewhere else. (Right now django handles it for me in most places, so I don't want to add it just for this one minor functionality) – maniexx Oct 03 '16 at 14:56