f-stringで改行 '\ n'を使用してPython 3.6で出力をフォーマットする方法


109

このケースをf文字列でPythonの方法でフォーマットする方法を知りたいです。

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

問題は、f-stringの式部分の'\'中で使用できないこと{...}です。予想される出力:

Winners are:
Adam
Bob
Cyril

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

回答:


123

できません。中かっこの中にバックスラッシュを置くことはできません{}。で結果そうしますSyntaxError

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

これはf-stringsのPEPで指定されています:

バックスラッシュは、f文字列の式部分の内部に表示されない場合があります[...]

1つのオプションは'\n'、名前に割り当ててから、.joinそのf-string 内に割り当てることです。つまり、リテラルを使用しません。

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

結果:

Winners are:
Adam
Bob
Cyril

@wimで指定されている別のオプションは、戻り値を使用chr(10)して\nそこに参加することです。f"Winners are:\n{chr(10).join(names)}"

もちろん、さらにもう1つは、'\n'.join事前に名前を追加することです。

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

結果は同じ出力になります。

注意:

これは、f-stringsとの小さな違いの1つですstr.format。後者では、対応する奇抜なディクショナリーがこれらのキーを含むアンパックされていることを認められた句読点をいつでも使用できます。

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

(これを行わないでください。)

前者では、句読点は使用できません。識別子を使用できないためです。


余談:他の回答が代替案として示唆しているように、私は間違いなくprintまたはを選択しますformat。私が指定したオプション、何らかの理由でf文字列を使用する必要がある場合にのみ適用されます。

何かが新しいからといって、それを使ってすべてを試す必要があるという意味ではありません;-)


55

区切り文字付きの文字列のリストを印刷するために、f文字列やその他のフォーマッタは必要ありません。sepキーワード引数を使用するだけprint()です:

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

出力:

Winners are:
Adam
Bob
Cyril

とはいえ、ここでstr.join()/を使用すると、str.format()f文字列の回避策よりも間違いなく単純で読みやすくなります。

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

13
これまでのベストアンサー。私は最近、print関数でstar unpackingを常に使用して、たとえばprint(*dir(some_object), sep='\n')やなどのオブジェクトの内部を調べていますprint(*vars(some_object), sep='\n')
Rickはモニカ

1
リストを直接印刷したくない場合、たとえばロガーにリストを渡す場合はどうしますか?
ボブ

1
@bob:次に、単にを使用しstr.join()ますtext = '\n'.join(['Winners are:', *names])。ところで、任意のファイルprint()への書き込みに使用できます(デフォルトでfile引数でsys.stdout指定)。
Eugene Yarmash

10

他の人が言ったようにf-stringsでバックスラッシュを使用することはできませんが、これを使用して回避することができますos.linesep(ただし、これは\nすべてのプラットフォームで使用できるわけではなく、バイナリファイルの読み取り/書き込みでない限り推奨されません。Rickのコメントを参照してください)。

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

それとも読みにくく方法で、しかしであることを保証\nし、chr()

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

2
私ではありませんでしたが、テキストを書くときに使用することos.linesepお勧めできません
Rickは2017年

1
@RickTeachey私はすでに括弧内に警告を追加し、別のアプローチを提案しました。とにかく、OPはテキストモードで開いたファイルに書き込むのではなく、画面に出力しています
Chris_Rands '27

それは重要ではないと思います。os.linesepただで読んで、または読み、バイナリモードで書き込むため。この場合も同じように機能することはわかっていますが、開始するのは悪い習慣です。繰り返しますが、私は反対投票ではありませんでした。警告は私には十分です。:)
Rickはモニカ

6

他の答えは、改行文字をf-stringフィールドに入れる方法についてのアイデアを提供します。ただし、OPの例(OPの実際の使用例を示す場合とそうでない場合がある)では、これらのアイデアを実際に使用するべきではないと私は主張します。

f-stringを使用する全体のポイントは、コードの可読性を向上させることです。f文字列でできることは何もできませんformat。これについてもっと読みやすいものがあるかどうかを慎重に検討してください(可能な場合)。

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

...またはこれ:

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

...またはこれ:

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

対これ:

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

最後の方法は、それ以上ではないにしても、少なくとも同じくらい読みやすいです。

要するに、光沢のある新しいものを持っているからといって、ドライバーが必要なときにハンマーを使用しないでください。コードは書かれているよりもずっと頻繁に読み込まれます。

他のユースケースについては、はい、そのchr(10)アイデアまたはnewlineアイデアが適切である可能性があります。しかし、与えられたもののためではありません。


7
可読性は主観的です:) ...古い慣習は熟練した人に適していて、場合によってはより読みやすいかもしれませんが、初心者にはほとんど知られていないため、彼らにとっては読めません。哲学的な観点で申し訳ありません。
2017年

2
@malmed読みやすさは一般に主観的ではありません。この場合は絶対にありません。しかし、詳細に議論する価値はありません。
Rickは2017年

@malmed読みやすさは、以前の経験でトレーニングできるという意味で「主観的」であるとあなたは正しい。しかし、私たちの脳と感覚には限界があるため、読みやすさは、関連するテキストをスキャンするのが物理的にどれほど簡単であるか、人間の脳が正確にパターン一致する傾向がある頻度、他の人の脳の予測にどの程度正確に示唆されているかという観点から客観的に測定できますコード(ステートメントの始まり/行の終わりを示唆する行を含む)、および初心者にとってどれほど読みやすくなるか。
mtraceur
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.