2012-04-15 7 views
5

Recientemente, encontré que la función ''.format es muy útil porque puede mejorar mucho la legibilidad en comparación con el formato %. Tratar de lograr sencillo formato de cadenas:función ".format" de python

data = {'year':2012, 'month':'april', 'location': 'q2dm1'} 

year = 2012 
month = 'april' 
location = 'q2dm1' 
a = "year: {year}, month: {month}, location: {location}" 
print a.format(data) 
print a.format(year=year, month=month, location=location) 
print a.format(year, month, location) 

mientras que dos primeras impresiones no formato que espero (sí, something=something se ve feo, pero eso es sólo un ejemplo), esta última debería aumentar KeyError: 'year'. ¿Hay algún truco en python para crear diccionario para que llene automáticamente las claves y los valores, por ejemplo somefunc(year, month, location) dará salida a {'year':year, 'month': month, 'location': location}?

Soy bastante nuevo en Python y no pude encontrar ninguna información sobre este tema, sin embargo, un truco como este mejoraría y reduciría drásticamente mi código actual.

Gracias de antemano y disculpen mi inglés.

Respuesta

6

La primera print debería ser

print a.format(**data) 

Además, si usted está encontrando algunos atajos, se podría escribir uno similar, no hay gran diferencia.

def trans(year, month, location): 
    return dict(year=year, month=month, location=location) 
+0

Parece que no hay forma de reducir este código de repetición :) La función es buena y fue lo que hice, en realidad, pero más tarde me resultó difícil de mantener porque con Había muchos argumentos que necesitaba para cambiar el código en varios lugares, lo que resultó ser aún peor que crear dict a mano. –

+0

@duke_nukem sí, depende de su uso real. El código está bien y el formato api es lo suficientemente claro. Si quieres algo como 'format (* args, ** kwargs)', también podría hacerse, pero no creo que pueda facilitar las cosas. – okm

1

Puede utilizar el exigible dict():

dict(year=yeah, month=month, location=location) 

Al pasar argumentos de palabra clave que crea un diccionario que contiene los elementos especificados como kwargs.

Si no desea especificar los nombres de los argumentos, utilice el estilo posicional de .format():

>>> a = 'year {0} month {1} location {2}' 
>>> print a.format(2012, 'april', 'abcd') 
year 2012 month april location abcd 

Sin embargo, si intenta hacer algo similar a lo que compact() in PHP no (crear un nombres de las variables de asignación dict a sus valores sin especificar el nombre y la variable por separado), por favor no. Simplemente da como resultado un código feo ilegible y requeriría hacks desagradables de todos modos.

+0

Sí, soy consciente de dict() pero estoy tratando de evitar el código innecesario y reducirlo un poco. .format puede aceptar su opción sin dict() por cierto. Gracias. –

+0

Gracias, está cerca de lo que necesito, sin embargo, con 10-12 argumentos se vuelve bastante difícil navegar a través de los índices. –

+0

Bueno, en este caso se supone que debes usar la sintaxis dict. Sin embargo, dependiendo de lo que quiera hacer, considere usar un motor de plantilla real como [jinja2] (http://jinja.pocoo.org/). – ThiefMaster

1

Se podía pasar locals():

a.format(**locals()) 

Por supuesto, esto no tiene problemas: tendrá que pasar todo en los locales, y puede ser difícil de entender el efecto del cambio de nombre o eliminar una variable .

Una mejor manera sería:

a.format(**{k:v for k,v in locals() if k in ('year', 'month')}) 
# or; note that if you move the lambda expression elsewhere, you will get a different result 
a.format(**(lambda ld = locals(): {k:ld[k] for k in ('year', 'month')})()) 

Pero esto no es más concisa, a menos que lo envuelve con una función (que por supuesto deben tener un parámetro dict).

3
data = {'year':2012, 'month':'april', 'location': 'q2dm1'} 
a = "year: {year}, month: {month}, location: {location}" 

print a.format(**data) 

..es lo que buscas. Es funcionalmente idéntico a hacer .format(year=data['year'], ...), o los otros ejemplos que proporcionó.

La cosa del doble asterisco es algo difícil de buscar, por lo que generalmente se la conoce como "kwargs".Esto es un good SO question on this syntax

0

A partir de Python 3.6, también puede utilizar la nueva Formatted string literals (f-strings), que se puede utilizar con variables de:

year = 2012 
month = 'april' 
location = 'q2dm1' 
a = f"year: {year}, month: {month}, location: {location}" 
print(a) 

o un diccionario:

data = {'year': 2012, 'month': 'april', 'location': 'q2dm1'} 
a = f"year: {data['year']}, month: {data['month']}, location: {data['location']}" 
print(a) 

Nota del f prefijo antes de la cadena literal.

PEP 498: Formatted string literals:

literales de cadena con formato tienen el prefijo 'f' y son similares a los cadenas de formato aceptado por str.format(). Contienen campos de reemplazo rodeados de llaves. Los campos de reemplazo son expresiones, que se evalúan en tiempo de ejecución, y luego formato utilizando el formato () protocolo:

>>> 
>>> name = "Fred" 
>>> f"He said his name is {name}." 
'He said his name is Fred.' 
>>> width = 10 
>>> precision = 4 
>>> value = decimal.Decimal("12.34567") 
>>> f"result: {value:{width}.{precision}}" # nested fields 
'result:  12.35' 

...