2

The goal is to use an f-string to round a float to a different number of decimal places based on the size of the number.

Is there in-line f-string formatting that works like the following function?

def number_format(x: float):
    if abs(x) < 10:
        return f"{x:,.2f}"  # thousands seperator for consistency
    if abs(x) < 100:
        return f"{x:,.1f}"
    return f"{x:,.0f}"  # this is the only one that actually needs the thousands seperator
cjm
  • 451
  • 4
  • 20
  • May I ask why you want to do this? – AMC Nov 26 '19 at 06:22
  • Are you trying to do it without using ANY function or can you use a function that calculates just the precision and use that output in the f-string? – Jack Fleeting Nov 26 '19 at 11:47
  • @AlexanderCécile Why do this? To display distances without extraneous precision. 0.25km makes sense for my use while 1,234.25km would be just as accurate displayed as 1,234km – cjm Nov 26 '19 at 18:01
  • @JackFleeting I’m asking this question to check if there is a built-in way to do this so that I don’t have to rely on my own function: if it’s in the standard library, I’d prefer to use that. – cjm Nov 26 '19 at 18:03
  • 1
    @cjm Makes sense. Unfortunately I don't know of a better way to do this :/ At least you can call the function inside the f-string, so it could be worse. – AMC Nov 26 '19 at 18:04
  • [This](https://stackoverflow.com/a/25780090/8164958) may help. The `g` format specifier displays desired numbers of significant digits. Just be aware that numbers beyond the chosen number of digits will be displayed in `e+` format, so choose the number of digits accordingly. – Seb Nov 26 '19 at 22:34

2 Answers2

1

Although it is not something that can go in-line in an f-string, the following is a generic number rounding formatter that isn't hard-coded to have a maximum of two digits to the right of the decimal point (unlike the example code in the question).

def number_format(x: float, d: int) -> str:
    """
    Formats a number such that adding a digit to the left side of the decimal
    subtracts a digit from the right side
    :param x: number to be formatter
    :param d: number of digits with only one number to the left of the decimal point
    :return: the formatted number
    """
    assert d >= 0, f"{d} is a negative number and won't work"
    x_size: int = 0 if not x else int(log(abs(x), 10))  # prevent error on x=0
    n: int = 0 if x_size > d else d - x_size  # number of decimal points
    return f"{x:,.{n}f}"
cjm
  • 451
  • 4
  • 20
-2

If I understood the question correctly, in python-3.x you can do

value = 10000
print(f'{value:,}')  # prints 10,000

and in python-2.x,

print('{:,}'.format(value))  # prints 10,000

For the rounding part you can do

def number_format(x: float):
    if abs(x) < 10:
        x = round(x, 2)
        return f"{x:,}"  # thousands seperator for consistency
    if abs(x) < 100:
        x = round(x, 1)
        return f"{x:,}"
    return f"{x:,}"
learner
  • 3,168
  • 3
  • 18
  • 35