Locale-agnostic: use _ as the thousand separator
f'{value:_}' # For Python ≥3.6
Note that this will NOT format in the user's current locale and will always use _ as the thousand separator, so for example:
1234567 ⟶ 1_234_567
English style: use , as the thousand separator
'{:,}'.format(value) # For Python ≥2.7
f'{value:,}' # For Python ≥3.6
Locale-aware
import locale
locale.setlocale(locale.LC_ALL, '') # Use '' for auto, or force e.g. to 'en_US.UTF-8'
'{:n}'.format(value) # For Python ≥2.7
f'{value:n}' # For Python ≥3.6
Reference
Per Format Specification Mini-Language,
The
','option signals the use of a comma for a thousands separator. For a locale aware separator, use the'n'integer presentation type instead.
and:
Answer from Ian Schneider on Stack OverflowThe
'_'option signals the use of an underscore for a thousands separator for floating point presentation types and for integer presentation type'd'. For integer presentation types'b','o','x', and'X', underscores will be inserted every 4 digits.
Locale-agnostic: use _ as the thousand separator
f'{value:_}' # For Python ≥3.6
Note that this will NOT format in the user's current locale and will always use _ as the thousand separator, so for example:
1234567 ⟶ 1_234_567
English style: use , as the thousand separator
'{:,}'.format(value) # For Python ≥2.7
f'{value:,}' # For Python ≥3.6
Locale-aware
import locale
locale.setlocale(locale.LC_ALL, '') # Use '' for auto, or force e.g. to 'en_US.UTF-8'
'{:n}'.format(value) # For Python ≥2.7
f'{value:n}' # For Python ≥3.6
Reference
Per Format Specification Mini-Language,
The
','option signals the use of a comma for a thousands separator. For a locale aware separator, use the'n'integer presentation type instead.
and:
The
'_'option signals the use of an underscore for a thousands separator for floating point presentation types and for integer presentation type'd'. For integer presentation types'b','o','x', and'X', underscores will be inserted every 4 digits.
I'm surprised that no one has mentioned that you can do this with f-strings in Python 3.6+ as easy as this:
>>> num = 10000000
>>> print(f"{num:,}")
10,000,000
... where the part after the colon is the format specifier. The comma is the separator character you want, so f"{num:_}" uses underscores instead of a comma. Only "," and "_" is possible to use with this method.
This is equivalent of using format(num, ",") for older versions of python 3.
This might look like magic when you see it the first time, but it's not. It's just part of the language, and something that's commonly needed enough to have a shortcut available. To read more about it, have a look at the group subcomponent.
How to use python with comma (,) instead of dot (.) as decimal separator?
You convert it before printing.
>>> print(str(3.5).replace(".",","))
3,5Above code converts 3.5 to string, then replaces dot with comma.
More on reddit.compython - How to format a float with a comma as decimal separator in an f-string? - Stack Overflow
How do I change my float into a two decimal number with a comma as a decimal point separator in python? - Stack Overflow
How to format a number with comma and specified precision digits in Python - Stack Overflow
Hi, I'm using python with some brazillian datasets and locale settings and when transforming some data python give for example 3.5, than then is interpreted as 35 in other applications that use that data.
How can I specify python to output 3,5 instead of 3.5, for example?
Thanks.
You convert it before printing.
>>> print(str(3.5).replace(".",","))
3,5
Above code converts 3.5 to string, then replaces dot with comma.
There is an 'n' formatting option, instead of the 'd' option, that is "locale aware". Worth testing to see if it works for you:
https://docs.python.org/3/library/string.html#format-specification-mini-language
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'
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!)
To get two decimals, use
'%.2f' % 1.2333333
To get a comma, use replace():
('%.2f' % 1.2333333).replace('.', ',')
A second option would be to change the locale to some place which uses a comma and then use locale.format():
locale.setlocale(locale.LC_ALL, 'FR')
locale.format('%.2f', 1.2333333)
The locale module can help you with reading and writing numbers in the locale's format.
>>> import locale
>>> locale.setlocale(locale.LC_ALL, "")
'sv_SE.UTF-8'
>>> locale.format("%f", 2.2)
'2,200000'
>>> locale.format("%g", 2.2)
'2,2'
>>> locale.atof("3,1415926")
3.1415926000000001
In Python 2.7 and 3.x you can use str.format for this:
>>> num = 1234567890.0876543
>>> "{0:,f}".format(num)
'1,234,567,890.087654'
>>> "{0:,.2f}".format(num)
'1,234,567,890.08'
>>> "{0:,f}".format(1234)
'1,234.000000'
I don't think you looked deep enough into the locale module. locale.format() is what you want, but make sure you set a locale first or you won't get grouping at all.
>>> locale.setlocale(locale.LC_ALL, '')
'en_US.UTF-8'
>>> locale.format("%.4f", 12345.678912, grouping=True)
'12,345.6789'
As an alternative to beerbajay's excellent answer, simple string formatting works in 2.7+, without requiring an import:
>>> '{0:,.2f}'.format(24322.34)
'24,322.34'
You can use the locale.format() function to do this:
>>> import locale
>>> locale.setlocale(locale.LC_ALL, 'en_US.utf8')
'en_US.utf8'
>>> locale.format("%.2f", 100028282.23, grouping=True)
'100,028,282.23'
Note that you have to give the precision: %.2f
Alternatively you can use the locale.currency() function, which follow the LC_MONETARY settings:
>>> locale.currency(100028282.23)
'$100028282.23'
Let's say I have 2792819, now I want it to be like 2,792,819. How do I do it?
I can do so while reversing it and after every 3 iterations, put a comma or something like that. But is there a better way to do so?
Using the localization services
The default locale
The standard library locale module is Python's interface to C-based localization routines.
The basic usage is:
import locale
locale.atof('123,456')
In locales where , is treated as a thousands separator, this would return 123456.0; in locales where it is treated as a decimal point, it would return 123.456.
However, by default, this will not work:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.8/locale.py", line 326, in atof
return func(delocalize(string))
ValueError: could not convert string to float: '123,456'
This is because by default, the program is "in a locale" that has nothing to do with the platform the code is running on, but is instead defined by the POSIX standard. As the documentation explains:
Initially, when a program is started, the locale is the
Clocale, no matter what the user’s preferred locale is. There is one exception: theLC_CTYPEcategory is changed at startup to set the current locale encoding to the user’s preferred locale encoding. The program must explicitly say that it wants the user’s preferred locale settings for other categories by callingsetlocale(LC_ALL, '').
That is: aside from making a note of the system's default setting for the preferred character encoding in text files (nowadays, this will likely be UTF-8), by default, the locale module will interpret data the same way that Python itself does (via a locale named C, after the C programming language). locale.atof will do the same thing as float passed a string, and similarly locale.atoi will mimic int.
Using a locale from the environment
Making the setlocale call mentioned in the above quote from the documentation will pull in locale settings from the user's environment. Thus:
>>> import locale
>>> # passing an empty string asks for a locale configured on the
>>> # local machine; the return value indicates what that locale is.
>>> locale.setlocale(locale.LC_ALL, '')
'en_CA.UTF-8'
>>> locale.atof('123,456.789')
123456.789
>>> locale.atof('123456.789')
123456.789
The locale will not care if the thousands separators are in the right place - it just recognizes and filters them:
>>> locale.atof('12,34,56.789')
123456.789
In 3.6 and up, it will also not care about underscores, which are separately handled by the built-in float and int conversion:
>>> locale.atof('12_34_56.789')
123456.789
On the other side, the string format method, and f-strings, are locale-aware if the n format is used:
>>> f'{123456.789:.9n}' # `.9` specifies 9 significant figures
'123,456.789'
Without the previous setlocale call, the output would not have the comma.
Setting a locale explicitly
It is also possible to make temporary locale settings, using the appropriate locale name, and apply those settings only to a specific aspect of localization. To get localized parsing and formatting only for numbers, for example, use LC_NUMERIC rather than LC_ALL in the setlocale call.
Here are some examples:
>>> # in Denmark, periods are thousands separators and commas are decimal points
>>> locale.setlocale(locale.LC_NUMERIC, 'en_DK.UTF-8')
'en_DK.UTF-8'
>>> locale.atof('123,456.789')
123.456789
>>> # Formatting a number according to the Indian lakh/crore system:
>>> locale.setlocale(locale.LC_NUMERIC, 'en_IN.UTF-8')
'en_IN.UTF-8'
>>> f'{123456.789:9.9n}'
'1,23,456.789'
The necessary locale strings may depend on your operating system, and may require additional work to enable.
To get back to how Python behaves by default, use the C locale described previously, thus: locale.setlocale(locale.LC_ALL, 'C').
Caveats
Setting the locale affects program behaviour globally, and is not thread safe. If done at all, it should normally be done just once at the beginning of the program. Again quoting from documentation:
It is generally a bad idea to call
setlocale()in some library routine, since as a side effect it affects the entire program. Saving and restoring it is almost as bad: it is expensive and affects other threads that happen to run before the settings have been restored.
If, when coding a module for general use, you need a locale independent version of an operation that is affected by the locale (such as certain formats used with
time.strftime()), you will have to find a way to do it without using the standard library routine. Even better is convincing yourself that using locale settings is okay. Only as a last resort should you document that your module is not compatible with non-Clocale settings.
When the Python code is embedded within a C program, setting the locale can even affect the C code:
Extension modules should never call
setlocale(), except to find out what the current locale is. But since the return value can only be used portably to restore it, that is not very useful (except perhaps to find out whether or not the locale isC).
(N.B: when setlocale is called with a single category argument, or with None - not an empty string - for the locale name, it does not change anything, and simply returns the name of the existing locale.)
So, this is not meant as a tool, in production code, to try out experimentally parsing or formatting data that was meant for different locales. The above examples are only examples to illustrate how the system works. For this purpose, seek a third-party internationalization library.
However, if the data is all formatted according to a specific locale, specifying that locale ahead of time will make it possible to use locale.atoi and locale.atof as drop-in replacements for int and float calls on string input.
Just remove the , with replace():
float("123,456.908".replace(',',''))