Come utilizzare la nuova riga '\ n' in f-string per formattare l'output in Python 3.6?


109

Vorrei sapere come formattare questa custodia in modo pitonico con stringhe in f:

names = ['Adam', 'Bob', 'Cyril']
text = f"Winners are:\n{'\n'.join(names)}"
print(text)

Il problema è che '\'non può essere utilizzato all'interno delle {...}parti di espressione di una stringa f. Uscita prevista:

Winners are:
Adam
Bob
Cyril

10
f"Winners are:\n{chr(10).join(names)}"
wim

Risposte:


123

Non puoi. Le barre rovesciate non possono apparire all'interno delle parentesi graffe {}; così facendo si ottiene SyntaxError:

>>> f'{\}'
SyntaxError: f-string expression part cannot include a backslash

Questo è specificato nella PEP per F-stringhe:

I backslash potrebbero non apparire all'interno delle parti di espressione delle stringhe f, [...]

Un'opzione è assegnare '\n'un nome e poi .joinquello all'interno della fstringa; cioè senza usare un letterale:

names = ['Adam', 'Bob', 'Cyril']
nl = '\n'
text = f"Winners are:{nl}{nl.join(names)}"
print(text)

Risultati in:

Winners are:
Adam
Bob
Cyril

Un'altra opzione, come specificato da @wim, è usare chr(10)per essere \nrestituiti e poi unirsi lì.f"Winners are:\n{chr(10).join(names)}"

Ancora un altro, ovviamente, è '\n'.joinprima e poi aggiungere il nome di conseguenza:

n = "\n".join(names)
text = f"Winners are:\n{n}"

che si traduce nello stesso output.

Nota:

Questa è una delle piccole differenze tra f-strings e str.format. In quest'ultimo, puoi sempre usare la punteggiatura a condizione che venga decompresso un dict stravagante corrispondente che contiene quelle chiavi:

>>> "{\\} {*}".format(**{"\\": 'Hello', "*": 'World!'})
"Hello World!"

(Per favore, non farlo.)

Nel primo caso, la punteggiatura non è consentita perché non è possibile avere identificatori che li utilizzano.


A parte: opterei sicuramente per printo format, come suggeriscono le altre risposte come alternativa. Le opzioni che ho fornito si applicano solo se per qualche motivo devi usare le stringhe f.

Solo perché qualcosa è nuovo, non significa che dovresti provare a farci tutto ;-)


55

Non hai bisogno di stringhe f o altri formattatori per stampare un elenco di stringhe con un separatore. Usa semplicemente l' separgomento della parola chiave per print():

names = ['Adam', 'Bob', 'Cyril']
print('Winners are:', *names, sep='\n')

Produzione:

Winners are:
Adam
Bob
Cyril

Detto questo, l'uso di str.join()/str.format() qui sarebbe probabilmente più semplice e più leggibile di qualsiasi soluzione alternativa alla stringa f:

print('\n'.join(['Winners are:', *names]))
print('Winners are:\n{}'.format('\n'.join(names)))

13
La migliore risposta finora. Al giorno d'oggi uso sempre lo star unpacking nella funzione di stampa per dare un'occhiata all'interno di qualche oggetto, ad esempio print(*dir(some_object), sep='\n')o print(*vars(some_object), sep='\n').
Rick sostiene Monica il

1
Cosa fare se non si desidera stampare direttamente l'elenco, ad esempio se lo si passa a un logger?
bob

1
@bob: poi basta usare str.join(): text = '\n'.join(['Winners are:', *names]). BTW, print()può essere utilizzato per scrivere su qualsiasi file (specificato con l' fileargomento, sys.stdoutper impostazione predefinita).
Eugene Yarmash

10

Non puoi usare i backslash nelle stringhe f come altri hanno detto, ma puoi aggirare questo usando os.linesep(anche se nota che non sarà \nsu tutte le piattaforme e non è raccomandato a meno che non legga / scrivi file binari; vedi i commenti di Rick ):

>>> import os
>>> names = ['Adam', 'Bob', 'Cyril']
>>> print(f"Winners are:\n{os.linesep.join(names)}")
Winners are:
Adam
Bob
Cyril 

O forse in un modo meno leggibile, ma garantito \n, con chr():

>>> print(f"Winners are:\n{chr(10).join(names)}")
Winners are:
Adam
Bob
Cyril

2
Non ero io, ma l'uso nonos.linesep è una buona idea durante la scrittura del testo.
Rick sostiene Monica il

1
@ RickTeachey Ho già aggiunto l'avvertenza tra parentesi e ho suggerito un approccio alternativo. Ad ogni modo, l'OP sta stampando sullo schermo, non scrivendo su un file aperto in modalità testo
Chris_Rands,

Non credo sia importante. os.linesepè solo per leggere, o leggere e scrivere in modalità binaria . So che funzionerà allo stesso modo in questo caso, ma iniziare è una cattiva abitudine. Ma ancora: non ero il downvote. L'avvertenza è abbastanza buona per me. :)
Rick sostiene Monica il

6

Le altre risposte danno idee su come inserire il carattere di nuova riga in un campo stringa f. Tuttavia, direi che per l'esempio fornito dal PO (che può o non può essere indicativo del caso d'uso effettivo del PO), nessuna di queste idee dovrebbe essere effettivamente utilizzata.

L'intero punto di utilizzo delle stringhe f è aumentare la leggibilità del codice. Non c'è niente che puoi fare con le stringhe f con cui non puoi fare format. Considera attentamente se c'è qualcosa di più leggibile in questo (se puoi farlo):

f"Winners are:\n{'\n'.join(names)}"

...o questo:

newline = '\n'
f"Winners are:\n{newline.join(names)}"

...o questo:

"Winners are:\n{chr(10).join(names)}"

contro questo:

"Winners are:\n{}".format('\n'.join(names))

L'ultimo modo è almeno altrettanto leggibile, se non di più.

In breve: non usare un martello quando ti serve un cacciavite solo perché ne hai uno nuovo brillante. Il codice viene letto molto più spesso di quanto non venga scritto.

Per altri casi d'uso, sì, è possibile che l' chr(10)idea o l' newlineidea possa essere appropriata. Ma non per quello dato.


7
La leggibilità è soggettiva :) ... la vecchia pratica si adatta a quelli esperti e può essere più leggibile in alcuni casi, ma può essere quasi sconosciuta ai noob e quindi illeggibile per loro. Scusa per il punto di vista filosofico.
malmed

2
La leggibilità di @malmed generalmente non è soggettiva. Sicuramente non in questo caso. Ma non vale la pena discuterne a lungo.
Rick sostiene Monica il

@malmed Hai ragione sul fatto che la leggibilità è "soggettiva" nel senso che è allenabile per esperienza precedente. Ma poiché il nostro cervello e i nostri sensi hanno dei limiti, la leggibilità può essere misurata oggettivamente in termini di quanto sia fisicamente facile scansionare il testo pertinente, quanto spesso i cervelli umani tendono ad abbinarlo correttamente, quanto correttamente allude alle previsioni del nostro cervello su altri codice (compreso l'inizio di un'istruzione / riga che suggerisce quale sarà la fine) e quanto facilmente diventa più leggibile per un principiante.
mtraceur
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.