Formateo de cadenas en Python 3

114

Hago esto en Python 2:

"(%d goals, $%d)" % (self.goals, self.penalties)

¿Cuál es la versión Python 3 de esto?

Intenté buscar ejemplos en línea, pero seguí obteniendo versiones de Python 2.

JoseBazBaz
fuente
No fue desaprobado; tu código funciona bien. Leer más aquí .
jackcogdill
32
Nota para el lector casual: el signo de dólar no tiene un significado especial. Aquí es solo un signo de dólar. (Gracias Martijn Pieters)
kevinarpe
1
pyformat.info y python-course.eu/python3_formatted_output.php (No mis sitios)
Christophe Roussy
1
El signo del dólar hizo que esta muy confuso ..
cchamberlain

Respuestas:

173

Aquí están los documentos sobre la sintaxis de formato "nuevo". Un ejemplo sería:

"({:d} goals, ${:d})".format(self.goals, self.penalties)

Si ambos goalsy penaltiesson números enteros (es decir, su formato predeterminado es correcto), podría abreviarse a:

"({} goals, ${})".format(self.goals, self.penalties)

Y dado que los parámetros son campos de self, también hay una forma de hacerlo usando un solo argumento dos veces (como @Burhan Khalid señaló en los comentarios):

"({0.goals} goals, ${0.penalties})".format(self)

Explicando:

  • {} significa solo el siguiente argumento posicional, con formato predeterminado;
  • {0}significa el argumento con índice 0, con formato predeterminado;
  • {:d} es el siguiente argumento posicional, con formato de entero decimal;
  • {0:d}es el argumento con índice 0, con formato de entero decimal.

Hay muchas otras cosas que puede hacer al seleccionar un argumento (usar argumentos con nombre en lugar de posicionales, acceder a campos, etc.) y también muchas opciones de formato (rellenar el número, usar separadores de miles, mostrar signo o no, etc.). Algunos otros ejemplos:

"({goals} goals, ${penalties})".format(goals=2, penalties=4)
"({goals} goals, ${penalties})".format(**self.__dict__)

"first goal: {0.goal_list[0]}".format(self)
"second goal: {.goal_list[1]}".format(self)

"conversion rate: {:.2f}".format(self.goals / self.shots) # '0.20'
"conversion rate: {:.2%}".format(self.goals / self.shots) # '20.45%'
"conversion rate: {:.0%}".format(self.goals / self.shots) # '20%'

"self: {!s}".format(self) # 'Player: Bob'
"self: {!r}".format(self) # '<__main__.Player instance at 0x00BF7260>'

"games: {:>3}".format(player1.games)  # 'games: 123'
"games: {:>3}".format(player2.games)  # 'games:   4'
"games: {:0>3}".format(player2.games) # 'games: 004'

Nota: Como señalaron otros, el nuevo formato no reemplaza al anterior, ambos están disponibles tanto en Python 3 como en las versiones más recientes de Python 2. Algunos pueden decir que es una cuestión de preferencia, pero en mi humilde opinión, el más nuevo es mucho más expresivo que el anterior, y debe usarse siempre que se escriba un código nuevo (a menos que se dirija a entornos más antiguos, por supuesto).

mgibsonbr
fuente
9
También puedes hacerlo"({0.goals} goals, ${0.penalties})".format(self)
Burhan Khalid
Debe tomar el '%' fuera de las llaves, por ejemplo, {: .2f%} -> {: .2f}%
SuperElectric
@SuperElectric quieres decir, en esta línea "conversion rate: {:.2%}".format(self.goals / self.shots):? Funciona bien para mí tal como está ... (Python 3.4) Tenga en cuenta que no hay fen él, estoy pidiendo formatear como un porcentaje, no como un número de punto flotante.
mgibsonbr
Tienes razón; parece funcionar en Python 3.4, así que está bien ya que el OP estaba preguntando por Python3. Descubrí que no funcionaba con Python 2.7.6. "{:.2f}%".format(float_num)funciona bien para ambos.
SuperElectric
1
@JohnSchmitt Sí, se suponía que este ejemplo daría exactamente el mismo resultado que el código dado en la pregunta. El $no tiene un significado especial aquí, ni en la sintaxis del formato antiguo ni en el nuevo, por lo que debería estar presente en la cadena generada, sin cambios.
mgibsonbr
67

Python 3.6 ahora admite la interpolación de cadenas literales abreviadas con PEP 498 . Para su caso de uso, la nueva sintaxis es simplemente:

f"({self.goals} goals, ${self.penalties})"

Esto es similar al .formatestándar anterior , pero permite hacer cosas como :

>>> width = 10
>>> precision = 4
>>> value = decimal.Decimal('12.34567')
>>> f'result: {value:{width}.{precision}}'
'result:      12.35'
JDong
fuente
12

Esa línea funciona como está en Python 3.

>>> sys.version
'3.2 (r32:88445, Oct 20 2012, 14:09:29) \n[GCC 4.5.2]'
>>> "(%d goals, $%d)" % (self.goals, self.penalties)
'(1 goals, $2)'
Mark Reed
fuente
OKAY. FRIO. Después de publicar la pregunta, continuaba mi búsqueda y descubrí que teníamos que hacer {% d} en lugar de solo% d, ¿es eso correcto también? ¿O es la forma Python2 la única forma de hacerlo?
JoseBazBaz
2
Python 3 introduce una nueva sintaxis, que son las llaves, pero no es necesario que la uses. Puede utilizar el antiguo o el nuevo. Pero son diferentes; si usa curlies, no usa signos de porcentaje.
Mark Reed
2

Me gusta este enfoque

my_hash = {}
my_hash["goals"] = 3 #to show number
my_hash["penalties"] = "5" #to show string
print("I scored %(goals)d goals and took %(penalties)s penalties" % my_hash)

Tenga en cuenta las dys adjuntas a los corchetes respectivamente.

la salida será:

I scored 3 goals and took 5 penalties
fullstacklife
fuente