2

I tried:

import locale
print(locale.locale_alias)
locale.setlocale(locale.LC_ALL, '')
locale.setlocale(locale.LC_NUMERIC, "french")
print(f"{3.14:.2f}")

but the output is 3.14 whereas I would like 3,14.

How to do this with f"..." string formatting?

Note: I don't want to use .replace(".", ",")

Note: I'm looking for a Windows solution, and solutions from How to format a float with a comma as decimal separator in an f-string? don't work (thus it's not a duplicate on Windows):

locale.setlocale(locale.LC_ALL, 'nl_NL')
# or
locale.setlocale(locale.LC_ALL, 'fr_FR')

locale.Error: unsupported locale setting

Basj
  • 41,386
  • 99
  • 383
  • 673
  • 1
    @matszwecja No, I'm on Windows, and these methods don't work out-of-the-box. – Basj Jan 10 '23 at 10:43
  • 1
    I've just tested and all 3 methods in accepted answer work just fine on Windows for me – matszwecja Jan 10 '23 at 10:45
  • 1
    If I use your code and change `print(f"{3.14:.2f}")` to `print(f"{3.14:.3n}")` I get `3,14` as described in one of the answers. – Cow Jan 10 '23 at 10:47
  • @user56700 You're right. I think you can post it as an answer. – Basj Jan 10 '23 at 10:49
  • @matszwecja In my case with `.3f` it does not work, but with `.3n` it does – Basj Jan 10 '23 at 10:50
  • @Basj The solution is from linked question, so it's still a clear duplicate for me. Regardless, keep in mind that `n` option only uses current locale. The code is not guaranteed to print it with comma if your current locale does not support that. – matszwecja Jan 10 '23 at 10:58
  • @matszwecja The strange thing is that `.2f` prints 2 digits after `.`, but with `.2n` we *only* have 1 digit after `,`. Why? Thus `.3n` is needed here. – Basj Jan 10 '23 at 11:04

3 Answers3

3

I looked up the answers on the duplicate flagged page and found an answer that worked:

Change print(f"{3.14:.2f}") to print(f"{3.14:.3n}") and you will get the result: 3,14

See https://docs.python.org/3/library/string.html#format-specification-mini-language:

'n' Number. This is the same as 'g', except that it uses the current locale setting to insert the appropriate number separator characters.

Whereas 'g' is described at:

g General format. For a given precision p >= 1, this rounds the number to p significant digits and then formats the result in either fixed-point format or in scientific notation, depending on its magnitude. A precision of 0 is treated as equivalent to a precision of 1. ...Truncated...

The 'f' description is:

'f' Fixed-point notation. For a given precision p, formats the number as a decimal number with exactly p digits following the decimal point.

Cow
  • 2,543
  • 4
  • 13
  • 25
  • 1
    The strange thing is that `.2f` prints 2 digits after `.`, but with `.2n` we *only* have 1 digit after `,`. Why? – Basj Jan 10 '23 at 11:11
  • 1
    @Basj You copied the integer notation description, where it should've been the float description. I've updated the answer. Btw thanks for adding the link etc. `n` is rounding the last digit, that's why you need 3. – Cow Jan 10 '23 at 11:18
1

You can use "locale.format_string" instead of "f string"

Try this instead :

import locale
# Set the locale to "french"
locale.setlocale(locale.LC_ALL, 'fr_FR.UTF-8')
# Format the number 3.14 with 2 decimal places, using the french locale
print(locale.format_string("%.2f", 3.14, grouping=True))
venkat sai
  • 11
  • 3
1

A bit of time has elapsed after the question, but I will add an answer for future reference.

As the other answers have indicated, n will automatically pick up your locale settings (which is one of its purposes), but the precision number works differently to what you anticipate. 3.14:.2n indicated that you want 2 digits. This isn't referring to the number of decimal places in the number, but to the overall number. So decimal places will be rounded down if necessary.

f is used to control decimal precision, but does not support locale formatting. To use the f notation in a locale sensitive way, it is necessary to format the number using locale.format_string() function:

import locale
locale.setlocale(locale.LC_NUMERIC, "fr_FR.UTF-8")
print(f"{3.14:.3n}")
# 3,14
print(f"{3.14:.2n}")
# 3,1
print(f"{3.14:.1n}")
# 3
print(locale.format_string("%.2f", 3.14))
# 3,14

If you want to use n formatter, and still require decimal precision, then the round() function is an option.

print(f'{round(3.14, 2):n}')
# 3,14
Andj
  • 481
  • 3
  • 8