¿Cómo puedo imprimir caracteres literales entre llaves en una cadena de Python y también usar .format en él?


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

me da Key Error: Hello\\

Quiero imprimir la salida: {Hello} 42



99
Para aquellos que desean evitar doblar las llaves ( {{ }}), use string.Template. Allí puede sustituir los identificadores de la forma $foo(útil para generar código LaTeX).
— Ioannis Filippidis

Para aquellos que desean evitar duplicar llaves, y que no son reacios a agregar otra dependencia a sus proyectos de Python, también existe Jinja2 que resuelve definitivamente este problema, permitiendo la sintaxis delimitador de marcador de posición personalizado definido por el usuario.
— dreftymac

Respuestas:


2072

Necesita duplicar {{y }}:

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

Aquí está la parte relevante de la documentación de Python para la sintaxis de cadenas de formato :

Las cadenas de formato contienen "campos de reemplazo" rodeados de llaves {}. Cualquier cosa que no esté contenida entre llaves se considera texto literal, que se copia sin cambios a la salida. Si necesita incluir un carácter de llave en el texto literal, se puede escapar doblando: {{y }}.


264
Entonces, si desea imprimir "{42}", ¡lo usaría "{{{0}}}".format(42)!
— hughes

77
¿Qué pasa si quieres una sola llave? "{ something { } {value}".format(42)no funciona
— AJP

14
"{{" .format () y "}}". format () imprimen llaves simples. En su ejemplo: imprima "{{algo {{}} {0}". Format (42) imprimirá "{algo {} 42".
— Mark Visser

2
¿Qué significa {0}eso?
— CodyBugstein

66
@ Imray: se {0}refiere al primer argumento de .format(). Puede imprimir más de un valor {0} {1} {2}, siempre y cuando le dé el mismo número de argumentos .format(). Consulte docs.python.org/library/string.html#format-examples para ver ejemplos extensos.
— Greg Hewgill

74

Te escapas doblando los frenos.

P.ej:

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

60

Python 3.6+ (2017)

En las versiones recientes de Python se usarían cadenas f (ver también PEP498 ).

Con las cadenas f se debe usar doble {{o}}

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

produce el deseado

 {Hello} 42

Si necesita resolver una expresión entre paréntesis en lugar de usar texto literal, necesitará tres conjuntos de paréntesis:

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

produce

{hello}

46

El OP escribió este comentario:

Intenté formatear un pequeño JSON para algunos propósitos, como este: '{"all": false, "selected": "{}"}'.format(data)para obtener algo como{"all": false, "selected": "1,2"}

Es bastante común que surja el problema de "frenos de escape" cuando se trata de JSON.

Sugiero hacer esto:

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

Es más limpio que la alternativa, que es:

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

Usar la jsonbiblioteca es definitivamente preferible cuando la cadena JSON se vuelve más complicada que el ejemplo.


1
¡Amén! Puede parecer más trabajo, pero usar bibliotecas para hacer lo que se supone que deben hacer las bibliotecas en lugar de cortar esquinas ... hace mejores cosas.
— Kaolin Fire

1
Pero el orden de las claves en un objeto Python no está garantizado ... Aún así, la biblioteca JSON está garantizada para serializarse de una manera JSON.
— wizzwizz4

2
wizzwizz4: Buen punto. Desde Python 3.6 en adelante, los diccionarios están ordenados por inserción, por lo que no sería un problema. Las versiones de Python entre 2.7 y 3.5 pueden usar OrderedDict de la biblioteca de colecciones.
— twasbrillig 01 de

24

Intenta hacer esto:

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


14

Aunque no es mejor, solo como referencia, también puede hacer esto:

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

Puede ser útil, por ejemplo, cuando alguien quiere imprimir {argument}. Es quizás más legible que'{{{}}}'.format('argument')

Tenga en cuenta que omite las posiciones de argumento (por ejemplo, en {}lugar de {0}) después de Python 2.7


5

Si va a hacer esto mucho, podría ser bueno definir una función de utilidad que le permita utilizar sustitutos de llaves arbitrarios, como

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}'

Tenga en cuenta que esto funcionará ya sea con corchetes que son una cadena de longitud 2 o un iterable de dos cadenas (para delimitadores de varios caracteres).


Pensé en eso también. Por supuesto, eso también funcionará y el algoritmo es más simple. Pero, imagina que tienes mucho texto como este, y solo quieres parametrizarlo aquí y allá. Cada vez que cree una cadena de entrada, no querrá reemplazar todas esas llaves manualmente. Simplemente querrás 'colocar' tus parametrizaciones aquí y allá. En este caso, creo que este método es más fácil de pensar y lograr desde la perspectiva del usuario. Me inspiró el comando 'sed' de Linux que tiene capacidades similares para elegir arbitrariamente su delimitador en función de lo que sea conveniente.
— tvt173

En resumen, prefiero que la función de utilidad sea un poco más compleja que tener un dolor en el uso de @ $$ cada vez. Avíseme si entendí mal su propuesta.
— tvt173

Continué y agregué una breve demostración a mi espacio public.lab
— dreftymac

3

Recientemente me encontré con esto, porque quería inyectar cadenas en JSON preformateado. Mi solución fue crear un método auxiliar, como este:

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

Luego puedes hacer algo como:

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

Hace el trabajo si el rendimiento no es un problema.


Simple y elegante para integrar en el código existente con poca modificación requerida. ¡Gracias!
— Columna01

2

Si necesita mantener dos llaves en la cuerda, necesita 5 llaves en cada lado de la variable.

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

Para aquellos que usan cadenas f, use 4 llaves en cada lado en lugar de 5
— TerryA

0

La razón es que {}es la sintaxis de .format()lo que en su caso .format()no reconoce, {Hello}por lo que arrojó un error.

puedes anularlo usando llaves dobles {{}},

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

o

intente %sformatear el texto,

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

0

Me topé con este problema al intentar imprimir texto, que puedo copiar y pegar en un documento de Latex. Extiendo esta respuesta y hago uso de los campos de reemplazo con nombre:

Digamos que desea imprimir un producto de múltiples variables con índices como ingrese la descripción de la imagen aquí, que en Latex sería $A_{ 0042 }*A_{ 3141 }*A_{ 2718 }*A_{ 0042 }$ El siguiente código hace el trabajo con campos con nombre para que para muchos índices permanezca legible:

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

-1

Si desea imprimir solo una llave (por ejemplo {), puede usarla {{, y puede agregar más llaves más adelante en la cadena si lo desea. Por ejemplo:

>>> f'{{ there is a curly brace on the left. Oh, and 1 + 1 is {1 + 1}'
'{ there is a curly brace on the left. Oh, and 1 + 1 is 2'

-1

Cuando solo intentas interpolar cadenas de código, te sugiero que uses jinja2, que es un motor de plantillas con todas las funciones para Python, es decir:

from jinja2 import Template

foo = Template('''
#include <stdio.h>

void main() {
    printf("hello universe number {{number}}");
}
''')

for i in range(2):
    print(foo.render(number=i))

Por lo tanto, no se le exigirá que duplique las llaves como lo sugieren todas las otras respuestas


-3

Puede hacer esto utilizando el método de cadena sin procesar simplemente agregando el carácter 'r' sin comillas antes de la cadena.

# to print '{I am inside braces}'
print(r'{I am inside braces}')

¡Hola! Es posible que desee volver a verificar eso; Impresiones Python 3.7 \{I am inside braces\}.
— Teodor

1
@Teodor lo siento por eso. Ahora arreglé esto imprimiendo como cadena sin procesar.
— Harsh Aggarwal
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.