Formattazione delle stringhe in Python 3


114

Lo faccio in Python 2:

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

Qual è la versione Python 3 di questo?

Ho provato a cercare esempi online ma ho continuato a ricevere le versioni di Python 2.


Non è stato deprecato; il tuo codice funziona bene. Leggi di più qui .
jackcogdill

32
Nota per il lettore occasionale: il segno del dollaro non ha un significato speciale. È solo un segno di dollaro qui. (Grazie Martijn Pieters)
kevinarpe


1
Il segno del dollaro ha reso tutto questo molto confuso ..
cchamberlain

Risposte:


173

Ecco i documenti sulla sintassi del "nuovo" formato. Un esempio potrebbe essere:

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

Se entrambi goalse penaltiessono numeri interi (cioè il loro formato predefinito è ok), potrebbe essere abbreviato in:

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

E poiché i parametri sono campi di self, c'è anche un modo per farlo usando un singolo argomento due volte (come ha notato @Burhan Khalid nei commenti):

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

spiegazione:

  • {} significa solo il successivo argomento posizionale, con il formato predefinito;
  • {0}indica l'argomento con indice 0, con formato predefinito;
  • {:d} è il successivo argomento posizionale, con formato intero decimale;
  • {0:d}è l'argomento con indice 0, con formato intero decimale.

Ci sono molte altre cose che puoi fare quando selezioni un argomento (usando argomenti con nome invece di quelli posizionali, accedendo ai campi, ecc.) E anche molte opzioni di formato (riempire il numero, usare migliaia di separatori, mostrare segno o meno, ecc.). Alcuni altri esempi:

"({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: come altri hanno sottolineato, il nuovo formato non sostituisce il primo, entrambi sono disponibili sia in Python 3 che nelle versioni più recenti di Python 2. Alcuni potrebbero dire che è una questione di preferenze, ma IMHO il più recente è molto più espressivo del vecchio e dovrebbe essere usato ogni volta che si scrive nuovo codice (a meno che non si rivolga ad ambienti più vecchi, ovviamente).


9
Puoi anche farlo"({0.goals} goals, ${0.penalties})".format(self)
Burhan Khalid

Devi prendere il '%' al di fuori delle parentesi graffe, ad esempio {: .2f%} -> {: .2f}%
SuperElectric

@SuperElectric vuoi dire, in questa linea: "conversion rate: {:.2%}".format(self.goals / self.shots)? Funziona bene per me così com'è ... (Python 3.4) Nota che non c'è f, sto chiedendo di formattare come percentuale, non come numero in virgola mobile.
mgibsonbr

Hai ragione; sembra funzionare in Python 3.4, quindi va bene poiché l'OP chiedeva informazioni su Python3. Ho appena scoperto che non funzionava con Python 2.7.6. "{:.2f}%".format(float_num)funziona bene per entrambi.
SuperElectric

1
@JohnSchmitt Sì, questo esempio avrebbe dovuto fornire lo stesso risultato esatto del codice fornito nella domanda. Il $non ha alcun significato speciale qui, né nella sintassi del vecchio formato né nel nuovo, quindi dovrebbe essere presente nella stringa generata, invariata.
mgibsonbr

67

Python 3.6 ora supporta l'interpolazione di stringhe letterali abbreviate con PEP 498 . Per il tuo caso d'uso, la nuova sintassi è semplicemente:

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

Questo è simile allo .formatstandard precedente , ma consente di fare facilmente cose come :

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

12

Quella linea funziona così com'è in 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)'

OK. FREDDO. Dopo aver pubblicato la domanda, stavo continuando la ricerca e ho scoperto che dobbiamo fare {% d} invece di% d, è corretto anche questo? O il modo in Python2 è l'unico modo per farlo?
JoseBazBaz

2
Python 3 introduce una nuova sintassi, ovvero le parentesi graffe, ma non è necessario utilizzarla. Puoi usare il vecchio o il nuovo. Ma sono diversi; se stai usando i ricci, non usi i segni di percentuale.
Mark Reed

2

Mi piace questo approccio

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)

Notare rispettivamente la d e la s alle parentesi.

l'output sarà:

I scored 3 goals and took 5 penalties
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.