6

I would like to do some simple math while I'm doing string formatting. For example

N = {'number':3}
four = '{number:d + 1}'.format(**N)

This doesn't work (of course). Is there a way to accomplish this that I'm not aware of?

Thanks!

jlconlin
  • 14,206
  • 22
  • 72
  • 105
  • 7
    Um, do it outside of the string? –  Jun 21 '11 at 20:53
  • 1
    You can subclass `Formatter` (https://github.com/ipython/ipython/blob/master/IPython/utils/text.py#L577) if you really want to. But generally it's recommended to do maths in code, and just let the formatter do formatting. – Thomas K Jun 21 '11 at 20:59
  • I was trying to avoid doing anything outside of the string. I need to use the same data in two places; in one place I need to add one and another the unmodified data. This is doable, but I was hoping there would be some Python magic that would solve this. There is every other time! That's why I love Python. – jlconlin Jun 22 '11 at 02:10

3 Answers3

6

"Is there a way to accomplish this that I'm not aware of?" If by "this" you mean encoding some mathematical logic in the format string using str.format, then no -- not that I'm aware of. However if you use a templating language you can express all kinds of stuff like this.

There are a billion different options for templating languages in Python, so rather than try to say which is best, I'll let you decide. See this article from the Python wiki: http://wiki.python.org/moin/Templating

A favorite of mine is Jinja2, although it's probably overkill for what you're talking about.

Here's an example of how to accomplish what you're after with Jinja2:

N = { 'd' : 3 }
four = Template(u'number:{{ d + 1 }}').render(**N)

The main advantage to a templating system like Jinja2 is that it allows you store templates as files separate from your application control logic such that you can maintain the view/presentation logic for your program in a way that limits or prohibits side effects from presentation execution.

Ben Burns
  • 14,978
  • 4
  • 35
  • 56
  • 1
    If you've ever used Django before, Jinja2 will be very easy to pick up. – Wilduck Jun 21 '11 at 21:37
  • Thanks for your comment. I figured it wasn't very likely that I could do what I wanted to do. Templating seems like it would work, but is way overkill for what I'm trying to accomplish. Thanks! – jlconlin Jun 22 '11 at 02:09
1

About as close as you can get is to use positional arguments instead of keyword arguments:

four='{0:d}'.format(N['number']+1)

or the shorter old-school:

four='%d'%(N['number']+1)

What's your goal here?

Russell Borogove
  • 18,516
  • 4
  • 43
  • 50
  • I thought of that, but the string has way to many options for positional arguments to work well; I'd quickly get lost. – jlconlin Jun 22 '11 at 02:12
-1

It is year 2023, we can consider this solution here: https://stackoverflow.com/a/53671539/4563935

For your example, this works:

def fstr(template):
    return eval(f"f'{template}'")

number = 3
number_plus_one = "{number + 1}"
print(fstr(number_plus_one))

Ray
  • 170
  • 3
  • 10