Insertar el mismo valor varias veces al formatear una cadena

111

Tengo una cadena de esta forma

s='arbit'
string='%s hello world %s hello world %s' %(s,s,s)

Todos los% s de la cadena tienen el mismo valor (es decir, s). ¿Existe una forma mejor de escribir esto? (En lugar de enumerar s tres veces)

Goutham
fuente
2
Este %operador de cadena será "obsoleto en Python 3.1 y eliminado más tarde en algún momento" docs.python.org/release/3.0.1/whatsnew/… ahora me pregunto cuál es la forma más recomendada tanto para la compatibilidad de versiones como para la seguridad.
cregox
2
@Cawas Sé que es bastante tarde, pero me gusta usar str.format(). Ej .: query = "SELECT * FROM {named_arg}"; query.format(**kwargs), donde queryes la cadena de formato y kwargses un diccionario con claves que coinciden con la named_args en la cadena de formato.
Edwin
4
@Cawas Sí, excepto Adam usa la notación tupla, donde {0}, {1}, {2}etc., corresponden a los índices de tupla 0, 1y 2, respectivamente. Alternativamente, también es posible nombrar los argumentos (como {named_arg}) y configurar cada uno en el método de formato, así:'Hi {fname} {lname}!'.format(fname='John', lname='Doe')
Edwin
2
@bignose Has marcado ambas preguntas como duplicadas entre sí, es como google.com/…
abhi

Respuestas:

203

Puede usar el formato de cadena avanzado , disponible en Python 2.6 y Python 3.x:

incoming = 'arbit'
result = '{0} hello world {0} hello world {0}'.format(incoming)
Adam Rosenfield
fuente
11
~ mi preferencia personal, opta por el estilo result = '{st} hello world {st} hello world {st}'.format(st=incoming)
kwargs
40
incoming = 'arbit'
result = '%(s)s hello world %(s)s hello world %(s)s' % {'s': incoming}

Es posible que desee leer esto para comprender: Operaciones de formato de cadena .

mhawke
fuente
1
Agradable. Se había olvidado de esto. locals () también lo hará.
Goutham
2
@Goutham: La respuesta de Adam Rosenfield podría ser mejor si su versión de Python está actualizada.
mhawke
En realidad es. Todavía me estoy acostumbrando a las nuevas operaciones de formateo de cadenas.
Goutham
3
incluso mejor, puede multiplicar la cadena base: '% (s) s hello world' * 3% {'s': 'asdad'}
dalloliogm
15

Puede utilizar el tipo de formato de diccionario:

s='arbit'
string='%(key)s hello world %(key)s hello world %(key)s' % {'key': s,}
Lucas S.
fuente
1
Parece tener muy poco sentido proporcionar esta respuesta duplicada. Aquí hay otro: '% (string_goes_here) s hola mundo% (string_goes_here) s hola mundo% (string_goes_here) s'% {'string_goes_here': s,}. Prácticamente hay infinitas posibilidades.
mhawke
3
mhawke: publiqué el mensaje antes de que mi navegador recargara la página, así que no supe en ese momento que la pregunta ya estaba respondida. ¡¡No necesitas ser grosero !!.
Lucas S.
2
@Lucas: Supongo que es posible que te tomó 13 minutos escribir tu respuesta :) y gracias por el voto negativo ... muy apreciado.
mhawke
13

Depende de lo que quieras decir con mejor. Esto funciona si su objetivo es eliminar la redundancia.

s='foo'
string='%s bar baz %s bar baz %s bar baz' % (3*(s,))
jjames
fuente
3
>>> s1 ='arbit'
>>> s2 = 'hello world '.join( [s]*3 )
>>> print s2
arbit hello world arbit hello world arbit
Whiterocker
fuente
Supongo que el ejemplo de la pregunta no era sobre 'hola mundo' repetido, sino una plantilla real sin duplicación. Por eso voté en contra.
Gra
1

Fstrings

Si está utilizando Python 3.6+, puede hacer uso del nuevo llamado f-stringsque significa cadenas formateadas y se puede usar agregando el carácter fal comienzo de una cadena para identificar esto como una cadena f .

price = 123
name = "Jerry"
print(f"{name}!!, {price} is much, isn't {price} a lot? {name}!")
>Jerry!!, 123 is much, isn't 123 a lot? Jerry!

Los principales beneficios de usar f-strings es que son más legibles, pueden ser más rápidos y ofrecen un mejor rendimiento:

Fuente Pandas para todos: análisis de datos de Python, por Daniel Y. Chen

Benchmarks

No hay duda de que los nuevos f-stringsson más legibles, ya que no tiene que reasignar las cadenas, pero ¿es más rápido como se indica en la cita mencionada anteriormente?

price = 123
name = "Jerry"

def new():
    x = f"{name}!!, {price} is much, isn't {price} a lot? {name}!"


def old():
    x = "{1}!!, {0} is much, isn't {0} a lot? {1}!".format(price, name)

import timeit
print(timeit.timeit('new()', setup='from __main__ import new', number=10**7))
print(timeit.timeit('old()', setup='from __main__ import old', number=10**7))
> 3.8741058271543776  #new
> 5.861819514350163   #old

Al ejecutar 10 millones de pruebas, parece que las nuevas f-stringsson en realidad más rápidas en el mapeo.

usuario1767754
fuente