19

For some machine control in python, I write the results to a text-file, that someone else can copy into Excel (this is the most convenient way in this situation). However, in the Netherlands, Excel has a comma as decimal separator and thus I want to have the result "position" in the text-file as 123,456, but when I use the f-string method like this:

    resultfile.write(f"Position\t{position:.5}")

This will obviously result in a dot decimal separator.

How can I change this to a comma without iterating through the whole file int the end and replace the dots with commas?

seaver
  • 351
  • 1
  • 2
  • 8
  • 2
    An fstring is just a string, so `f"Position\t{position:.5}".replace('.', ',')` should work just fine, right? – Arne Mar 27 '19 at 14:34
  • 2
    Also: https://stackoverflow.com/a/6633912/962190 This answer talks about a different issue (printing number with comma separation every three decimal positions), but the locale setting might influence your format as well. – Arne Mar 27 '19 at 14:35

5 Answers5

14

If you want to format floats with a comma within the f-string, you can either use replace after casting the float to a string:

position = 123.456
f"Position\t{str(position).replace('.',',')}"

A second option is to use the Python standard library module locale (but it is not thread-safe):

import locale
locale.setlocale(locale.LC_ALL, 'nl_NL')
f"Position\t{locale.format('%.3f', position)}"

A third option is to use the library babel (preferred in case of library routines):

from babel.numbers import format_decimal
f"Position\t{format_decimal(position, locale='nl_NL')}"

All three options return the same result for the given example:

'Position\t123,456'
kadee
  • 8,067
  • 1
  • 39
  • 31
3

As @michel-de-ruiter mentioned, the f format does not work with locale. On the other hand, you can't set the precision using n format. For example, if you want 4 digits after decimal separator:

import locale
locale.setlocale(locale.LC_ALL, 'nl_NL')

position = 123.45678999
print(f'{position:.4n}')  # output: 123,4 (not quite what we wanted!)

However, you can round the number with the desired precision before formatting it:

print(f'{round(position, 4):n}')  # output: 123,4567 (that's it!)
Baumann
  • 1,119
  • 11
  • 20
3

If you prefer to avoid dependencies, the following simple function might fit your needs:

def comma_num(n,f=''):
    return ('{'+f+'}').format(n).replace('.',',')

n = 1.23

f'Whatever {comma_num(n)}'
'Whatever {}'.format(comma_num(n))
>>>'Whatever 1,23'

f'Whatever {comma_num(n,":6.4f")}'
'Whatever {}'.format(comma_num(n,':6.4f'))
>>>'Whatever 1,2300'
mmj
  • 5,514
  • 2
  • 44
  • 51
1

If the g format is good enough for you, use n instead:

resultfile.write(f"Position\t{position:.7n}")

While n works (uses the current locale setting when used) instead of both d and g, there is no such thing for the f format unfortunately...

Michel de Ruiter
  • 7,131
  • 5
  • 49
  • 74
-2

A simpler solution might be:

f"Position\t{position:,.5f}"
Anuvrat Parashar
  • 2,960
  • 5
  • 28
  • 55
user11616715
  • 45
  • 1
  • 2
  • 9
    This changes the _thousands separator_ to `,` but the question is asking about the _decimal separator_. It doesn't answer the question at all. – marcelm Aug 22 '20 at 08:19
  • @seaver This does *not* answer the question. All this does is introducing a thousands separator (`,`). It does *not* change the decimal separator (stays `.`). – Michel de Ruiter Dec 10 '20 at 11:16