68

How can I use f-string with logic to format an int as a float? I would like if ppl is True to format num to 2 decimal places, and if ppl is False to rformat it as whatever it is.

Something like string = f'i am {num:.2f if ppl else num}' but this does not work. The below code demonstrates the behaviour that I want to achieve with a simpler f-string if possible:

ppl = True
num = 3
string = f'I am {num:.2f}' if ppl else f'I am {num}'
print(string)
#if ppl False
#=> i am 3
#if ppl True
#=> i am 3.00
jacobcan118
  • 7,797
  • 12
  • 50
  • 95

2 Answers2

92

You can nest expressions to evaluate inside expressions in an f-string. This means you can move the ternary right inside your f-string:

string = f'I am {num:{".2f" if ppl else ""}}'

Note the additional pair of braces needed for nesting.

But I don't think this is cleaner. Personally I find it harder to parse what's going on here, as opposed to your clear original version. After all simple is better than complex; flat is better than nested.

  • 78
    this is disgusting and I like it – Ben Aug 16 '18 at 22:14
  • 4
    Also the `}}` handling is kind of confusing - usually `}}` means a literal closing brace, but here, `}}` closes two nested replacement fields. Looking at the [language reference](https://docs.python.org/3/reference/lexical_analysis.html#f-strings), I can see how the parsing rules work out that way, but it's still confusing. – user2357112 Aug 16 '18 at 22:27
  • @user2357112 agreed, if anything I prefer Gamrix' two-step version. – Andras Deak -- Слава Україні Aug 16 '18 at 22:28
22

I would recommend that you actually separate the fstring into two lines

num_str = f'{num:.2f}' if ppl else f'{num}'
final_str = f'I am {num_str}'

That way each line is as simple as it can be.

Gamrix
  • 661
  • 4
  • 12