LaVOZs

The World’s Largest Online Community for Developers

'; How can I print literal curly-brace characters in python string and also use .format on it? - LavOzs.Com

x = " \{ Hello \} {0} "
print(x.format(42))

gives me : Key Error: Hello\\

I want to print the output: {Hello} 42

You need to double the {{ and }}:

>>> x = " {{ Hello }} {0} "
>>> print(x.format(42))
' { Hello } 42 '

Here's the relevant part of the Python documentation for format string syntax:

Format strings contain “replacement fields” surrounded by curly braces {}. Anything that is not contained in braces is considered literal text, which is copied unchanged to the output. If you need to include a brace character in the literal text, it can be escaped by doubling: {{ and }}.

You escape it by doubling the braces.

Eg:

x = "{{ Hello }} {0}"
print(x.format(42))

Python 3.6+ (2017)

In the recent versions of Python one would use f-strings (see also PEP498).

With f-strings one should use double {{ or }}

n = 42  
print(f" {{Hello}} {n} ")

produces the desired

 {Hello} 42

If you need to resolve an expression in the brackets instead of using literal text you'll need three sets of brackets:

hello = "HELLO"
print(f"{{{hello.lower()}}}")

produces

{hello}

The OP wrote this comment:

I was trying to format a small JSON for some purposes, like this: '{"all": false, "selected": "{}"}'.format(data) to get something like {"all": false, "selected": "1,2"}

It's pretty common that the "escaping braces" issue comes up when dealing with JSON.

I suggest doing this:

import json
data = "1,2"
mydict = {"all": "false", "selected": data}
json.dumps(mydict)

It's cleaner than the alternative, which is:

'{{"all": false, "selected": "{}"}}'.format(data)

Using the json library is definitely preferable when the JSON string gets more complicated than the example.

Try doing this:

x = " {{ Hello }} {0} "
print x.format(42)

Try this:

x = "{{ Hello }} {0}"

Although not any better, just for the reference, you can also do this:

>>> x = '{}Hello{} {}'
>>> print x.format('{','}',42)
{Hello} 42

It can be useful for example when someone wants to print {argument}. It is maybe more readable than '{{{}}}'.format('argument')

Note that you omit argument positions (e.g. {} instead of {0}) after Python 2.7

If you are going to be doing this a lot, it might be good to define a utility function that will let you use arbitrary brace substitutes instead, like

def custom_format(string, brackets, *args, **kwargs):
    if len(brackets) != 2:
        raise ValueError('Expected two brackets. Got {}.'.format(len(brackets)))
    padded = string.replace('{', '{{').replace('}', '}}')
    substituted = padded.replace(brackets[0], '{').replace(brackets[1], '}')
    formatted = substituted.format(*args, **kwargs)
    return formatted

>>> custom_format('{{[cmd]} process 1}', brackets='[]', cmd='firefox.exe')
'{{firefox.exe} process 1}'

Note that this will work either with brackets being a string of length 2 or an iterable of two strings (for multi-character delimiters).

If you need to keep two curly braces in the string, you need 5 curly braces on each side of the variable.

>>> myvar = 'test'
>>> "{{{{{0}}}}}".format(myvar)
'{{test}}'

I recently ran into this, because I wanted to inject strings into preformatted JSON. My solution was to create a helper method, like this:

def preformat(msg):
    """ allow {{key}} to be used for formatting in text
    that already uses curly braces.  First switch this into
    something else, replace curlies with double curlies, and then
    switch back to regular braces
    """
    msg = msg.replace('{{', '<<<').replace('}}', '>>>')
    msg = msg.replace('{', '{{').replace('}', '}}')
    msg = msg.replace('<<<', '{').replace('>>>', '}')
    return msg

You can then do something like:

formatted = preformat("""
    {
        "foo": "{{bar}}"
    }""").format(bar="gas")

Gets the job done if performance is not an issue.

I stumbled upon this problem when trying to print text, which I can copy paste into a Latex document. I extend on this answer and make use of named replacement fields:

Lets say you want to print out a product of mulitple variables with indices such as enter image description here, which in Latex would be $A_{ 0042 }*A_{ 3141 }*A_{ 2718 }*A_{ 0042 }$ The following code does the job with named fields so that for many indices it stays readable:

idx_mapping = {'i1':42, 'i2':3141, 'i3':2178 }
print('$A_{{ {i1:04d} }} * A_{{ {i2:04d} }} * A_{{ {i3:04d} }} * A_{{ {i1:04d} }}$'.format(**idx_mapping))

Reason is , {} is the syntax of .format() so in your case .format() doesn't recognize {Hello} so it threw an error.

you can override it by using double curly braces {{}},

x = " {{ Hello }} {0} "

or

try %s for text formatting,

x = " { Hello } %s"
print x%(42)  

Using custom placeholder tokens with Jinja2

Context

  • python 3.x
  • alternative to string.format() that allows custom placeholder syntax
  • this approach uses Jinja2 for increased flexibility at the cost of performance and an additional python dependency

Problem

We want to use custom placeholder delimiters with python str.format()

  • string.format() is powerful, but no native support for placeholder delimiter modification.
  • string.format() uses curly-brace which is very common, and and causes Delimiter collision
  • string.format() default workaround is to double-up the delimiters. This can be cumbersome, because it requires changing your original source, when changing the default placeholder delimiter is arguably more straight-forward.

Solution

We can use Jinja2 as an alternative to python str.format()

  • import jinja2 as an additional dependency
  • wrap jinja2 with a custom class that makes the sytnax substantially similar to that of str.format()
  • permit other enhancements such as custom functions and filters

Advantages

Drawbacks

  • adds an additional dependency on Jinja2
  • less performant that built-in python str.format
  • Jinja2 has a different debugging experience than pure python

Example: Demo use of a custom Jinja2-based str.format() alternative

  • we wrote a custom TPLjinja class that makes Jinja work more like python str.format()
# import custom class
import TPLjinja
import textwrap
#;;

# prepare source data
ddmydata = dict()
ddmydata['fname'] = 'Huomer'
ddmydata['lname'] = 'Huimpson'
ddmydata['motto'] = 'I love donuts!'
#;;

# prepare template
sgtemplate = textwrap.dedent('''\
Hello @{fname} @{lname}!
We love your motto: ```@{motto}``` and we agree with you!
''')
#;;

# show output
vout = TPLjinja(template=sgtemplate,delimiter="@",wrap="{").format(**ddmydata)
print(vout)
#;;

# show how easy it is to change the delimiter syntax
# vout = TPLjinja(template='''Hello $<fname> !''',delimiter="$",wrap="<").format(**ddmydata)
# vout = TPLjinja(template='''Hello ~(fname) !''',delimiter="~",wrap="(").format(**ddmydata)
# vout = TPLjinja(template='''Hello &<%fname%> !''',delimiter="&",wrap="<%").format(**ddmydata)
#;;

See also

You can do this by using raw string method by simply adding character 'r' without quotes before the string.

# to print '{I am inside braces}'
print(r'{I am inside braces}')
Related
How to escape braces (curly brackets) in a format string in .NET
How can I pretty-print JSON in a shell script?
Accessing the index in 'for' loops?
Convert bytes to a string
How do I sort a dictionary by value?
How do I get a substring of a string in Python?
Check if a given key already exists in a dictionary
How do I lowercase a string in Python?
Why does this code using random strings print “hello world”?