Formato de cadena:% vs. formato.

1350

Python 2.6 introdujo el str.format()método con una sintaxis ligeramente diferente del %operador existente . ¿Cuál es mejor y para qué situaciones?

  1. Lo siguiente usa cada método y tiene el mismo resultado, entonces, ¿cuál es la diferencia?

    #!/usr/bin/python
    sub1 = "python string!"
    sub2 = "an arg"
    
    a = "i am a %s" % sub1
    b = "i am a {0}".format(sub1)
    
    c = "with %(kwarg)s!" % {'kwarg':sub2}
    d = "with {kwarg}!".format(kwarg=sub2)
    
    print a    # "i am a python string!"
    print b    # "i am a python string!"
    print c    # "with an arg!"
    print d    # "with an arg!"
    
  2. Además, ¿cuándo se produce el formateo de cadenas en Python? Por ejemplo, si mi nivel de registro está establecido en ALTO, ¿recibiré un golpe por realizar la siguiente %operación? Y si es así, ¿hay alguna manera de evitar esto?

    log.debug("some debug info: %s" % some_info)
NorthIsUp
fuente
2
Para principiantes: Aquí hay un tutorial muy bueno que enseña ambos estilos. Personalmente uso el %estilo más antiguo con más frecuencia, porque si no necesita las capacidades mejoradas del format()estilo, el %estilo suele ser mucho más conveniente.
Lutz Prechelt
2
A modo de referencia: Python 3 documentación para el nuevo format()estilo de formato y el mayor %estilo de formato basado .
Lutz Prechelt
1
Para responder a su segunda pregunta, desde 3.2 puede usar el formato {} si usa un formateador personalizado (consulte docs.python.org/3/library/logging.html#logging.Formatter )
yanjost el

Respuestas:

953

Para responder a su primera pregunta ... .formatsimplemente parece más sofisticado en muchos sentidos. Una cosa molesta %es también cómo puede tomar una variable o una tupla. Uno pensaría que lo siguiente siempre funcionaría:

"hi there %s" % name

sin embargo, si namees así (1, 2, 3), arrojará un TypeError. Para garantizar que siempre se imprima, deberías hacer

"hi there %s" % (name,)   # supply the single argument as a single-item tuple

lo cual es feo .formatNo tiene esos problemas. También en el segundo ejemplo que diste, el .formatejemplo tiene un aspecto mucho más limpio.

¿Por qué no lo usarías?

  • sin saberlo (yo antes de leer esto)
  • tener que ser compatible con Python 2.5

Para responder a su segunda pregunta, el formateo de cadenas ocurre al mismo tiempo que cualquier otra operación, cuando se evalúa la expresión de formateo de cadenas. Y Python, al no ser un lenguaje vago, evalúa las expresiones antes de llamar a las funciones, por lo que en su log.debugejemplo, la expresión "some debug info: %s"%some_infoprimero evaluará, por ejemplo "some debug info: roflcopters are active", luego se pasará esa cadena log.debug().

Claudiu
fuente
113
¿Qué pasa"%(a)s, %(a)s" % {'a':'test'}
Ted
128
Tenga en cuenta que perderá tiempo log.debug("something: %s" % x)pero no para log.debug("something: %s", x) El formato de cadena se manejará en el método y no obtendrá el impacto en el rendimiento si no se registra. Como siempre, Python anticipa tus necesidades =)
darkfeline
63
ted: es un truco de peor aspecto para hacer lo mismo '{0}, {0}'.format('test').
ovejas voladoras
19
El punto es: el único argumento recurrente de que la nueva sintaxis permite reordenar elementos es un punto discutible: puede hacer lo mismo con la sintaxis anterior. ¡La mayoría de la gente no sabe que esto ya está definido en el Ansi C99 Std! Echa un vistazo a una copia reciente man sprintfy aprende sobre la $notación dentro de los %marcadores de posición
cfi
29
@cfi: Si quiere decir algo así como printf("%2$d", 1, 3)imprimir "3", eso se especifica en POSIX, no en C99. La misma página de manual a la que hizo referencia señala: "El estándar C99 no incluye el estilo con '$' ...".
Thanatos
307

Algo que el operador de módulo (%) no puede hacer, afaik:

tu = (12,45,22222,103,6)
print '{0} {2} {1} {2} {3} {2} {4} {2}'.format(*tu)

resultado

12 22222 45 22222 103 22222 6 22222

Muy útil.

Otro punto: al format()ser una función, puede usarse como argumento en otras funciones:

li = [12,45,78,784,2,69,1254,4785,984]
print map('the number is {}'.format,li)   

print

from datetime import datetime,timedelta

once_upon_a_time = datetime(2010, 7, 1, 12, 0, 0)
delta = timedelta(days=13, hours=8,  minutes=20)

gen =(once_upon_a_time +x*delta for x in xrange(20))

print '\n'.join(map('{:%Y-%m-%d %H:%M:%S}'.format, gen))

Resultados en:

['the number is 12', 'the number is 45', 'the number is 78', 'the number is 784', 'the number is 2', 'the number is 69', 'the number is 1254', 'the number is 4785', 'the number is 984']

2010-07-01 12:00:00
2010-07-14 20:20:00
2010-07-28 04:40:00
2010-08-10 13:00:00
2010-08-23 21:20:00
2010-09-06 05:40:00
2010-09-19 14:00:00
2010-10-02 22:20:00
2010-10-16 06:40:00
2010-10-29 15:00:00
2010-11-11 23:20:00
2010-11-25 07:40:00
2010-12-08 16:00:00
2010-12-22 00:20:00
2011-01-04 08:40:00
2011-01-17 17:00:00
2011-01-31 01:20:00
2011-02-13 09:40:00
2011-02-26 18:00:00
2011-03-12 02:20:00
eyquem
fuente
17
Puede usar el formato de estilo antiguo con la mapmisma facilidad que el formato. map('some_format_string_%s'.__mod__, some_iterable)
AGF
3
@cfi: demuestre que tiene razón reescribiendo el ejemplo anterior en C99
MarcH
99
@MarcH: printf("%2$s %1$s\n", "One", "Two");compilado con gcc -std=c99 test.c -o test, la salida es Two One. Pero estoy corregido: en realidad es una extensión POSIX y no C. No puedo encontrarlo nuevamente en el estándar C / C ++, donde pensé que lo había visto. El código funciona incluso con la bandera estándar 'c90'. sprintfpágina man . Esto no lo enumera, pero permite que las bibliotecas implementen un superconjunto. Mi argumento original sigue siendo válido, reemplazando CconPosix
cfi
8
Mi primer comentario aquí, no se aplica a esta respuesta. Lamento la fraseología. En Python no podemos usar el operador de módulo %para reordenar marcadores de posición. Todavía me gustaría no eliminar ese primer comentario en aras de la coherencia de los comentarios aquí. Pido disculpas por haber desahogado mi ira aquí. Está dirigido contra la afirmación hecha a menudo de que la sintaxis anterior per se no permitiría esto. En lugar de crear una sintaxis completamente nueva, podríamos haber introducido las extensiones std Posix. Podríamos tener ambos.
cfi
17
'módulo' se refiere al operador que evalúa un resto después de una división. en este caso, el signo de porcentaje no es un operador de módulo.
Pulpo
148

Suponiendo que está utilizando el loggingmódulo de Python , puede pasar los argumentos de formato de cadena como argumentos al .debug()método en lugar de hacerlo usted mismo:

log.debug("some debug info: %s", some_info)

lo que evita hacer el formateo a menos que el registrador realmente registre algo.

Wooble
fuente
10
Esta es información útil que acabo de aprender ahora. Es una pena que no tenga su propia pregunta, ya que parece estar separada de la pregunta principal. Lástima que el OP no dividió su pregunta en dos preguntas separadas.
snth
12
Puede usar el formato dict de esta manera: log.debug("some debug info: %(this)s and %(that)s", dict(this='Tom', that='Jerry')) Sin embargo, no puede usar la nueva .format()sintaxis de estilo aquí, ni siquiera en Python 3.3, lo cual es una pena.
Cito
15
@Cito: Mira esto: plumberjack.blogspot.co.uk/2010/10/…
Vinay Sajip
26
El beneficio principal de esto no es el rendimiento (la interpolación de cadenas será rápida en comparación con lo que sea que esté haciendo con la salida del registro, por ejemplo, mostrar en un terminal, guardar en el disco) Es que si tiene un agregador de registro, puede decirle "obtuvo 12 instancias de este mensaje de error", incluso si todos tenían valores diferentes de 'some_info'. Si el formateo de la cadena se realiza antes de pasar la cadena a log.debug, entonces esto es imposible. El agregador solo puede decir "tenía 12 mensajes de registro diferentes"
Jonathan Hartley
77
Si le preocupa el rendimiento, use la sintaxis literal dict {} en lugar de una instanciación de clase dict (): doughellmann.com/2012/11/…
trojjer
119

A partir de Python 3.6 (2016) puede usar cadenas f para sustituir variables:

>>> origin = "London"
>>> destination = "Paris"
>>> f"from {origin} to {destination}"
'from London to Paris'

Tenga en cuenta el f"prefijo. Si intenta esto en Python 3.5 o anterior, obtendrá un SyntaxError.

Ver https://docs.python.org/3.6/reference/lexical_analysis.html#f-strings

Coronel Panic
fuente
1
Esto no responde la pregunta. Otra respuesta que menciona f-strings al menos habla sobre el rendimiento: stackoverflow.com/a/51167833/7851470
Georgy
60

PEP 3101 propone el reemplazo del %operador con el nuevo formato de cadena avanzado en Python 3, donde sería el predeterminado.

Idea genial
fuente
14
Falso: "La compatibilidad con versiones anteriores puede mantenerse manteniendo los mecanismos existentes en su lugar"; por supuesto, .formatno reemplazará el % formato de cadena.
Tobias
12
No, la postulación BrainStorms es verdadera: "destinada a reemplazar el '%' existente". La cita de Tobias significa que ambos sistemas coexistirán por algún tiempo. RTFPEP
phobie
54

Pero tenga cuidado, justo ahora descubrí un problema al intentar reemplazar todo %con el .formatcódigo existente: '{}'.format(unicode_string)intentará codificar unicode_string y probablemente fallará.

Solo mira este registro de sesión interactiva de Python:

Python 2.7.2 (default, Aug 27 2012, 19:52:55) 
[GCC 4.1.2 20080704 (Red Hat 4.1.2-48)] on linux2
; s='й'
; u=u'й'
; s
'\xd0\xb9'
; u
u'\u0439'

ses solo una cadena (llamada 'matriz de bytes' en Python3) y ues una cadena Unicode (llamada 'cadena' en Python3):

; '%s' % s
'\xd0\xb9'
; '%s' % u
u'\u0439'

Cuando le das un objeto Unicode como parámetro al %operador, producirá una cadena Unicode incluso si la cadena original no era Unicode:

; '{}'.format(s)
'\xd0\xb9'
; '{}'.format(u)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'latin-1' codec can't encode character u'\u0439' in position 0: ordinal not in range(256)

pero la .formatfunción generará "UnicodeEncodeError":

; u'{}'.format(s)
u'\xd0\xb9'
; u'{}'.format(u)
u'\u0439'

y funcionará con un argumento Unicode bien solo si la cadena original era Unicode.

; '{}'.format(u'i')
'i'

o si la cadena de argumento se puede convertir en una cadena (llamada 'matriz de bytes')

Wobmene
fuente
12
Simplemente no hay razón para cambiar el código de trabajo a menos que las características adicionales del nuevo formatmétodo sean realmente necesarias ...
Tobias
absolutamente de acuerdo con usted, Tobias, pero a veces es necesario al actualizar a versiones más nuevas de Python
wobmene
2
¿Por ejemplo? AFAIK, nunca ha sido necesario; No considero probable que la %interpolación de cadenas desaparezca.
Tobias
44
Considero que la función .format () es más segura que% para cadenas. A menudo veo errores de principiantes como este "p1=%s p2=%d" % "abc", 2o "p1=%s p2=%s" % (tuple_p1_p2,). Puede pensar que es culpa del codificador, pero creo que es una sintaxis defectuosa extraña que se ve bien para la escritura rápida pero es mala para el código de producción.
wobmene
3
Pero no me gusta la sintaxis de .format (), sería más feliz con los viejos %s, %02dcomo "p1=%s p2=%02d".format("abc", 2). Culpo a los que inventaron y aprobaron el formato de llaves que necesita que escapen {{}}y se ve feo en mi humilde opinión.
wobmene
35

Otra ventaja más .format(que no veo en las respuestas): puede tomar propiedades de objeto.

In [12]: class A(object):
   ....:     def __init__(self, x, y):
   ....:         self.x = x
   ....:         self.y = y
   ....:         

In [13]: a = A(2,3)

In [14]: 'x is {0.x}, y is {0.y}'.format(a)
Out[14]: 'x is 2, y is 3'

O, como argumento de palabra clave:

In [15]: 'x is {a.x}, y is {a.y}'.format(a=a)
Out[15]: 'x is 2, y is 3'

Esto no es posible con %lo que puedo decir.

matiasg
fuente
44
Esto parece más ilegible de lo necesario en comparación con el equivalente 'x is {0}, y is {1}'.format(a.x, a.y). Solo debe usarse cuando la a.xoperación es muy costosa.
dtheodor
13
@dtheodor Con un pellizco utilizar un argumento de palabra clave en lugar de argumento posicional ... 'x is {a.x}, y is {a.y}'.format(a=a). Más legible que ambos ejemplos.
CivFan
1
@CivFan O, si tiene más de un objeto,'x is {a.x}, y is {a.y}'.format(**vars())
Jack
1
También tenga en cuenta éste de la misma manera: '{foo[bar]}'.format(foo={'bar': 'baz'}).
Antoine Pinsard
3
Esto es increíblemente útil para aplicaciones orientadas al cliente, donde su aplicación proporciona un conjunto estándar de opciones de formato con una cadena de formato proporcionada por el usuario. Uso esto todo el tiempo. El archivo de configuración, por ejemplo, tendrá alguna propiedad de "cadena de mensajes", que el usuario puede suministrar Your order, number {order[number]} was processed at {now:%Y-%m-%d %H:%M:%S}, will be ready at about {order[eta]:%H:%M:%S}o lo que desee. Esto es mucho más limpio que tratar de ofrecer la misma funcionalidad con el antiguo formateador. Hace que las cadenas de formato proporcionadas por el usuario sean mucho más potentes.
Taywee
35

%da un mejor rendimiento que el formatde mi prueba.

Código de prueba:

Python 2.7.2:

import timeit
print 'format:', timeit.timeit("'{}{}{}'.format(1, 1.23, 'hello')")
print '%:', timeit.timeit("'%s%s%s' % (1, 1.23, 'hello')")

Resultado:

> format: 0.470329046249
> %: 0.357107877731

Python 3.5.2

import timeit
print('format:', timeit.timeit("'{}{}{}'.format(1, 1.23, 'hello')"))
print('%:', timeit.timeit("'%s%s%s' % (1, 1.23, 'hello')"))

Resultado

> format: 0.5864730989560485
> %: 0.013593495357781649

Se ve en Python2, la diferencia es pequeña, mientras que en Python3, %es mucho más rápido que format.

Gracias @Chris Cogdon por el código de muestra.

Editar 1:

Probado nuevamente en Python 3.7.2 en julio de 2019.

Resultado:

> format: 0.86600608
> %: 0.630180146

No hay mucha diferencia Supongo que Python está mejorando gradualmente.

Edición 2:

Después de que alguien mencionó la cadena f de python 3 en el comentario, hice una prueba para el siguiente código en python 3.7.2:

import timeit
print('format:', timeit.timeit("'{}{}{}'.format(1, 1.23, 'hello')"))
print('%:', timeit.timeit("'%s%s%s' % (1, 1.23, 'hello')"))
print('f-string:', timeit.timeit("f'{1}{1.23}{\"hello\"}'"))

Resultado:

format: 0.8331376779999999
%: 0.6314778750000001
f-string: 0.766649943

Parece que f-string es aún más lento %pero mejor que format.

lcltj
fuente
42
En cambio, str.formatofrece más funcionalidades (especialmente formato de tipo especializado, por ejemplo '{0:%Y-%m-%d}'.format(datetime.datetime.utcnow())). El rendimiento no puede ser el requisito absoluto de todos los trabajos. Use la herramienta adecuada para el trabajo.
minhee
36
"La optimización prematura es la raíz de todo mal", o eso dijo una vez Donald Knuth ...
Yatharth Agarwal
22
Seguir un esquema de formateo conocido (siempre que se adapte a las necesidades, lo que hace en la gran mayoría de los casos), y que es el doble de rápido, no es una "optimización prematura" sino simplemente razonable. Por cierto, el %operador permite reutilizar el printfconocimiento; La interpolación del diccionario es una extensión muy simple del principio.
Tobias
55
De hecho, he experimentado lo contrario en una situación. El formato de nuevo estilo fue más rápido. ¿Puede proporcionar el código de prueba que utilizó?
David Sanders
8
Parece una publicación seriamente desperdiciada sin ningún ejemplo o razonamiento, solo afirmaciones.
kevr
31

Como descubrí hoy, la antigua forma de formatear cadenas a través de %no es compatible Decimal, el módulo de Python para punto fijo decimal y aritmética de punto flotante, fuera de la caja.

Ejemplo (usando Python 3.3.5):

#!/usr/bin/env python3

from decimal import *

getcontext().prec = 50
d = Decimal('3.12375239e-24') # no magic number, I rather produced it by banging my head on my keyboard

print('%.50f' % d)
print('{0:.50f}'.format(d))

Salida:

0.00000000000000000000000312375239000000009907464850 0.00000000000000000000000312375239000000000000000000

Seguramente puede haber soluciones, pero aún puede considerar usar el format()método de inmediato.

balu
fuente
1
Probablemente se deba a que el formato de estilo nuevo llama str(d)antes de expandir el parámetro, mientras que el formato de estilo antiguo probablemente llama float(d)primero.
David Sanders
3
Uno pensaría que sí, pero str(d)regresa "3.12375239e-24", no"0.00000000000000000000000312375239000000000000000000"
Jack
18

Si su python> = 3.6, el literal con formato de F-string es su nuevo amigo.

Es más simple, limpio y mejor rendimiento.

In [1]: params=['Hello', 'adam', 42]

In [2]: %timeit "%s %s, the answer to everything is %d."%(params[0],params[1],params[2])
448 ns ± 1.48 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [3]: %timeit "{} {}, the answer to everything is {}.".format(*params)
449 ns ± 1.42 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [4]: %timeit f"{params[0]} {params[1]}, the answer to everything is {params[2]}."
12.7 ns ± 0.0129 ns per loop (mean ± std. dev. of 7 runs, 100000000 loops each)
zhengcao
fuente
15

Como nota al margen, no tiene que tomar un golpe de rendimiento para usar el nuevo formato de estilo con el registro. Puede pasar cualquier objeto a logging.debug, logging.info, etc., que implementa el __str__método mágico. Cuando el módulo de registro ha decidido que debe emitir su objeto de mensaje (sea lo que sea), llama str(message_object)antes de hacerlo. Entonces podrías hacer algo como esto:

import logging


class NewStyleLogMessage(object):
    def __init__(self, message, *args, **kwargs):
        self.message = message
        self.args = args
        self.kwargs = kwargs

    def __str__(self):
        args = (i() if callable(i) else i for i in self.args)
        kwargs = dict((k, v() if callable(v) else v) for k, v in self.kwargs.items())

        return self.message.format(*args, **kwargs)

N = NewStyleLogMessage

# Neither one of these messages are formatted (or calculated) until they're
# needed

# Emits "Lazily formatted log entry: 123 foo" in log
logging.debug(N('Lazily formatted log entry: {0} {keyword}', 123, keyword='foo'))


def expensive_func():
    # Do something that takes a long time...
    return 'foo'

# Emits "Expensive log entry: foo" in log
logging.debug(N('Expensive log entry: {keyword}', keyword=expensive_func))

Todo esto se describe en la documentación de Python 3 ( https://docs.python.org/3/howto/logging-cookbook.html#formatting-styles ). Sin embargo, también funcionará con Python 2.6 ( https://docs.python.org/2.6/library/logging.html#using-arbitrary-objects-as-messages ).

Una de las ventajas de usar esta técnica, además del hecho de que es independiente del estilo de formato, es que permite valores vagos, por ejemplo, la función expensive_funcanterior. Esto proporciona una alternativa más elegante a los consejos que se dan en los documentos de Python aquí: https://docs.python.org/2.6/library/logging.html#optimization .

David Sanders
fuente
2
Desearía poder votar esto más. Permite iniciar sesión formatsin el impacto en el rendimiento, lo hace al anular __str__precisamente como loggingse diseñó, acorta la llamada de función a una sola letra ( N) que se siente muy similar a algunas de las formas estándar de definir cadenas, Y permite la pereza función de llamada. ¡Gracias! +1
CivFan
2
¿Es esto diferente en resultado al uso del logging.Formatter(style='{')parámetro?
davidA
10

Una situación en la que %puede ayudar es cuando está formateando expresiones regex. Por ejemplo,

'{type_names} [a-z]{2}'.format(type_names='triangle|square')

plantea IndexError. En esta situación, puede usar:

'%(type_names)s [a-z]{2}' % {'type_names': 'triangle|square'}

Esto evita escribir la expresión regular como '{type_names} [a-z]{{2}}'. Esto puede ser útil cuando tiene dos expresiones regulares, donde una se usa sola sin formato, pero la concatenación de ambas está formateada.

Jorge Leitao
fuente
3
O simplemente usar '{type_names} [a-z]{{2}}'.format(type_names='triangle|square'). Es como decir que .format()puede ayudar cuando se usan cadenas que ya contienen un carácter de porcentaje. Por supuesto. Tienes que escapar de ellos entonces.
Alfe
1
@Alfe Tiene razón, y es por eso que la respuesta comienza con "One situation where % may help is when you are formatting regex expressions."Específicamente, suponga que a=r"[a-z]{2}"es un fragmento de expresión regular que se utilizará en dos expresiones finales diferentes (por ejemplo, c1 = b + ay c2 = a). Suponga que c1necesita ser formateditado (por ejemplo, bdebe estar formateado en tiempo de ejecución), pero c2no es así. Entonces necesitas a=r"[a-z]{2}"por c2y a=r"[a-z]{{2}}"para c1.format(...).
Jorge Leitao
7

Agregaría que desde la versión 3.6, podemos usar cadenas f como la siguiente

foo = "john"
bar = "smith"
print(f"My name is {foo} {bar}")

Que dan

Mi nombre es john smith

Todo se convierte en cuerdas.

mylist = ["foo", "bar"]
print(f"mylist = {mylist}")

Resultado:

mylist = ['foo', 'bar']

puede pasar la función, como en el método de otros formatos

print(f'Hello, here is the date : {time.strftime("%d/%m/%Y")}')

Dando por ejemplo

Hola, aquí está la fecha: 16/04/2018

Sylvan LE DEUNFF
fuente
4

Para la versión de Python> = 3.6 (ver PEP 498 )

s1='albha'
s2='beta'

f'{s1}{s2:>10}'

#output
'albha      beta'
Roushan
fuente
2

Python 3.6.7 comparativo:

#!/usr/bin/env python
import timeit

def time_it(fn):
    """
    Measure time of execution of a function
    """
    def wrapper(*args, **kwargs):
        t0 = timeit.default_timer()
        fn(*args, **kwargs)
        t1 = timeit.default_timer()
        print("{0:.10f} seconds".format(t1 - t0))
    return wrapper


@time_it
def new_new_format(s):
    print("new_new_format:", f"{s[0]} {s[1]} {s[2]} {s[3]} {s[4]}")


@time_it
def new_format(s):
    print("new_format:", "{0} {1} {2} {3} {4}".format(*s))


@time_it
def old_format(s):
    print("old_format:", "%s %s %s %s %s" % s)


def main():
    samples = (("uno", "dos", "tres", "cuatro", "cinco"), (1,2,3,4,5), (1.1, 2.1, 3.1, 4.1, 5.1), ("uno", 2, 3.14, "cuatro", 5.5),) 
    for s in samples:
        new_new_format(s)
        new_format(s)
        old_format(s)
        print("-----")


if __name__ == '__main__':
    main()

Salida:

new_new_format: uno dos tres cuatro cinco
0.0000170280 seconds
new_format: uno dos tres cuatro cinco
0.0000046750 seconds
old_format: uno dos tres cuatro cinco
0.0000034820 seconds
-----
new_new_format: 1 2 3 4 5
0.0000043980 seconds
new_format: 1 2 3 4 5
0.0000062590 seconds
old_format: 1 2 3 4 5
0.0000041730 seconds
-----
new_new_format: 1.1 2.1 3.1 4.1 5.1
0.0000092650 seconds
new_format: 1.1 2.1 3.1 4.1 5.1
0.0000055340 seconds
old_format: 1.1 2.1 3.1 4.1 5.1
0.0000052130 seconds
-----
new_new_format: uno 2 3.14 cuatro 5.5
0.0000053380 seconds
new_format: uno 2 3.14 cuatro 5.5
0.0000047570 seconds
old_format: uno 2 3.14 cuatro 5.5
0.0000045320 seconds
-----
Felix Martinez
fuente
3
Debe ejecutar cada ejemplo varias veces, una sola ejecución puede ser engañosa, por ejemplo, el sistema operativo puede estar ocupado en general, por lo que la ejecución de su código se retrasa. ver los documentos: docs.python.org/3/library/timeit.html . (¡buen avatar, Guybrush!)
jake77
1

Pero una cosa es que también si ha anidado llaves, no funcionará para el formato, pero %funcionará.

Ejemplo:

>>> '{{0}, {1}}'.format(1,2)
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    '{{0}, {1}}'.format(1,2)
ValueError: Single '}' encountered in format string
>>> '{%s, %s}'%(1,2)
'{1, 2}'
>>> 
U10-Adelante
fuente
2
podrías hacer esto, pero estoy de acuerdo en que es un formato '{{{0}, {1}}}'.
horrible
Las llaves anidadas funcionan bien y son bonitas.
CivFan