On 1/29/2018 2:13 AM, Nick Coghlan wrote:
On 29 January 2018 at 11:48, Nathaniel Smith
wrote: On Sun, Jan 28, 2018 at 5:31 PM, David Mertz
wrote: I actually didn't know about `locale.format("%d", 10e9, grouping=True)`. But it's still much less general than having the option in the f-string/.format() mini-language. This is really about the formatted string, not necessarily about the locale. So, e.g. I'd like to be able to write:
print(f"In European format x is {x:,.2f}, in Indian format it is {x:`.2f}")
I don't want the format necessarily to be some pseudo-global setting, even if it can get stored in thread-locals. That said, having a locale-aware symbol for delimiting numbers in the format mini-language would also not be a bad thing.
I don't understand the format mini-language well enough to know what would fit in, but maybe some way to (a) request localified formatting,
Given the example, I think a more useful approach would be to allow an optional digit grouping specifier after the comma separator, and allow the separator to be repeated to indicate non-uniform groupings in the lower order digits.
If we did that, then David's example could become:
>>> print(f"In European format x is {x:,.2f}, in Indian format it is {x:,2,3.2f}")
This just seems too complicated to me, and is overgeneralizing. How many of these different formats would ever really be used? Can you really expect someone to remember what that means by looking at it? If you are going to generalize it, at least go all the way and support the struct lconv "CHAR_MAX" behavior, too. However, I suggest just pick another character to use instead of ",", and have it mean the 2,3 format. With no evidence (and willing to be wrong), it seems like it's the next-most needed variety of this. Maybe use ";"? Eric
The core elements of interpreting that would then be:
- digit group size specifiers are permited for both "," (decimal display only) and "_" (all display bases) - if no digit group size specifier is given, it defaults to 3 for decimal and 4 for binary, octal, and hexadecimal - if multiple digit group specifiers are given, then the last one given is applied starting from the least significant integer digit
so "{x:,2,3.2f}" means:
- an arbitrary number of leading 2-digit groups - 1 group of 3 digits - 2 decimal places
It would then be reasonably straightforward to use this as a lower level primitive to implement locale dependent formatting, as follows:
- format in English using the locale's grouping rules [1] (either LC_NUMERIC.grouping or LC_MONETARY.mon_grouping, as appropriate) - use str.translate() [2] to replace "," and "." with the locale's thousands_sep & decimal_point or mon_thousands_sep & mon_decimal_point
[1] https://docs.python.org/3/library/locale.html#locale.localeconv [2] https://docs.python.org/3/library/stdtypes.html#str.translate
Cheers, Nick.