Chciałbym wiedzieć, jak sformatować ten przypadek w sposób Pythonic z F-Strings:

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

Problem polega na tym, że '\' nie można użyć wewnątrz części ekspresyjnych {...} f-ciąg F. Oczekiwany wynik:

Winners are:
Adam
Bob
Cyril
184
malmed 27 czerwiec 2017, 15:30

4 odpowiedzi

Najlepsza odpowiedź

Nie możesz. Odwrotne ukośniki nie mogą pojawić się wewnątrz kędzierzawego klamra {}; Zrób to powoduje SyntaxError:

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

Jest to określone w PEP dla F-Strings:

Montaż odwrotnych mogą nie pojawić się w części ekspresyjnych F-Strings, [...]

Jedną z opcji zapewnia '\n' do nazwy, a następnie {x1}} na tym wewnątrz f - ciąg; to znaczy bez użycia dosłownego:

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

Prowadzi do:

Winners are:
Adam
Bob
Cyril

Inna opcja, jak określono przez @wim, jest użycie chr(10), aby odzyskać \n, a następnie dołączyć do nich. f"Winners are:\n{chr(10).join(names)}"

Jeszcze inny, oczywiście, jest wcześniej '\n'.join, a następnie odpowiednio dodać nazwę:

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

Co powoduje to samo wyjście.

Uwaga:

Jest to jedna z małych różnic między f - ciągami i {x1}}. W tym drugim można zawsze użyć interpunkcji przyznanych, że odpowiednie Wacky Dict jest rozpakowany, który zawiera te klucze:

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

(Proszę nie robić tego.)

W pierwszym, interpunkcja nie jest dozwolona, ponieważ nie możesz mieć identyfikatorów, którzy je używają.


Na bok: na pewno zdecydowałem się na print lub format, ponieważ inne odpowiedzi sugerują jako alternatywa. Opcje, które udzielałem zastosowania tylko wtedy, gdy musi z jakiegoś powodu użyj f-sciąk.

Tylko dlatego, że coś jest nowe, nie oznacza, że powinieneś spróbować zrobić z tym wszystkim ;-)

144
Dimitris Fasarakis Hilliard 30 czerwiec 2017, 14:23

Nie możesz używać odwrotnych ukośników w F-Strings, jak inni powiedzieli, ale możesz wkroczyć do tego za pomocą os.linesep (choć uwaga nie będzie \n na wszystkich platformach i nie jest zalecany, chyba że czytanie / pisząc pliki binarne; patrz rick's Komentarze):

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

A może w mniej czytelny sposób, ale gwarantowany jest \n, z chr():

>>> print(f"Winners are:\n{chr(10).join(names)}")
Winners are:
Adam
Bob
Cyril
11
Chris_Rands 27 czerwiec 2017, 13:52

Pozostałe odpowiedzi nadają pomysły na umieszczenie znaku nowej linii w polu F-String. Jednakże, kłócę się, że dla przykładu OP dał (który może lub nie może być wskazujący na rzeczywisty przypadek użytkowania), żaden z tych pomysłów nie powinien być rzeczywiście użyty.

Cały punkt korzystania z ciągów F-ciągi jest zwiększenie czytelności kodu. Nie można nic zrobić z F-Strings, których nie możesz zrobić z format. Zastanów się uważnie, czy jest coś takiego bardziej czytelne (jeśli mógłbyś to zrobić):

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

...albo to:

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

...albo to:

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

Vs.

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

Ostatni jest przynajmniej tak czytelny, jeśli nie więcej.

Krótko mówiąc: nie używaj młotka, gdy potrzebujesz śrubokręta tylko dlatego, że masz błyszczący nowy. Kod jest czytany znacznie częściej niż jest napisany.

W przypadku innych przypadków użycia, tak, możliwe jest ideę chr(10) lub pomysł newline. Ale nie dla danego.

8
Rick supports Monica 27 czerwiec 2017, 13:26

Nie potrzebujesz F-Strings ani innych formatów do wydrukowania listy ciągów separator. Wystarczy użyć argumentu słów kluczowych sep do {x0}} / str.format() tutaj prawdopodobnie będzie prawdopodobnie proste i bardziej czytelne niż każdy f Obejście obejścia:

print('\n'.join(['Winners are:', *names]))
print('Winners are:\n{}'.format('\n'.join(names)))
56
Eugene Yarmash 3 luty 2020, 16:03