相关文章推荐
俊秀的葫芦  ·  android ...·  1 年前    · 
文雅的领结  ·  java - Junit 5 - No ...·  1 年前    · 

在Python 3.6中,如何在f-string中使用换行'\n'来格式化输出?

211 人关注

我想知道如何以Pythonic方式用f-strings格式化这种情况。

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

问题是,'\'不能在f-string的{...}表达式部分内使用。 预期的输出。

Winners are:
Cyril
    
1 个评论
wim
f"Winners are:\n{chr(10).join(names)}"
python
python-3.x
newline
python-3.6
f-string
malmed
malmed
发布于 2017-06-27
6 个回答
Dimitris Fasarakis Hilliard
Dimitris Fasarakis Hilliard
发布于 2021-10-29
已采纳
0 人赞同

你不能这样做。反斜线不能出现在大括号内 {} ;这样做的结果是 SyntaxError

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

This is specified in the PEP for f-strings:

反斜线不能出现在f-字符串的表达部分,[...] 。

一种选择是将'\n'分配给一个名字,然后在f-字符串内对其进行.join;也就是说,不使用字面。

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

Results in:

Winners are:
Cyril

另一个选择,如@wim所指定的,是使用chr(10)来获得\n的返回,然后在那里加入。【替换代码10

当然,还有一种方法是事先'\n'.join,然后再相应地添加名字。

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

其结果是相同的输出。

Note:

这是f-字符串和str.format之间的一个小区别。在后者中,你总是可以使用标点符号,授予一个相应的古怪的dict被解包,其中包含这些键。

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

(请不要这样做。)

在前者中,标点符号是不允许的,因为你不可能有使用标点符号的标识符。

另外:我肯定会选择printformat,正如其他答案所建议的那样,作为一种选择。我所给出的选项只适用于以下情况must出于某种原因,使用F字符串。

仅仅因为某些东西是新的,并不意味着你应该尝试用它来做所有事情;-)

Timo
对我来说没有意义。 nl = '\n' text = f"Winners are:{nl}" 。使用:text = f "Winners are:\n"
@Timo OP需要将 join 放在 \n 的格式字符串中,特别是嵌入表达式中。
Sam
我相信@timo的观点是第一个 {nl} 是没有必要的,因为 \n 不在f-string的表达部分。替换代码2】是完全可以的,是 {"\n".join()} 部分在f-string中引起了问题。
知道为什么f-strings会有这样的限制吗?例如,在JavaScript中,你可以在字符串模板中放置表达式,没有这种限制。
@RonInbar 在Python中,还有另外两种格式化字符串的方法,它们不存在这种限制,而且在f-strings之前就已经存在,它们是 '%s' % ('\n') '{}'.format('\n')
Eugene Yarmash
Eugene Yarmash
发布于 2021-10-29
0 人赞同

你不需要f-strings或其他格式化器来打印一个带有分隔符的字符串列表。只需使用 sep 的关键字参数到 print() :

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

Output:

Winners are:
Cyril

这就是说,使用str.join()/str.format()这里可以说比任何f-string的变通方法更简单,更易读。

print('\n'.join(['Winners are:', *names]))
print('Winners are:\n{}'.format('\n'.join(names)))
    
到目前为止的最佳答案。我最近一直在使用打印函数中的星形解包来查看一些对象的内部情况,例如: print(*dir(some_object), sep='\n') print(*vars(some_object), sep='\n')
bob
如果你不想直接打印列表,比如说你要把它传给一个记录器,你该怎么办?
@bob: then just use str.join() : text = '\n'.join(['Winners are:', *names]) . BTW, print() 可以用来写到 任何文件 (用 file 参数指定,默认为 sys.stdout )。
Chris_Rands
Chris_Rands
发布于 2021-10-29
0 人赞同

正如其他人所说,你不能在f字符串中使用反斜线,但你可以使用以下方法来解决这个问题 os.linesep (虽然注意到这并不是在所有的平台上都是 \n ,而且不建议使用,除非读/写二进制文件;见 Rick's comments):

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

或者,也许用一种不那么可读的方式,但保证是\n,用chr():

>>> print(f"Winners are:\n{chr(10).join(names)}")
Winners are:
Cyril
    
不是我,但使用 os.linesep 不是一个好主意 when writing text.
@RickTeachey 我已经在括号里加上了注意事项,并建议采用另一种方法。无论如何,OP是要打印到屏幕上,而不是写到以文本模式打开的文件中。
我认为这并不重要。 os.linesep 只是 用于读取,或以二进制模式读写 .我知道在这种情况下会有同样的效果,但这是一个坏习惯的开始。但还是那句话。我不是降权者。注意事项对我来说已经足够了。 :)
Rick supports Monica
Rick supports Monica
发布于 2021-10-29
0 人赞同

其他答案给出了如何将换行符放入f-string字段的想法。然而,我想说的是,对于OP给出的例子(可能是也可能不是OP的实际使用情况),这些想法实际上都不应该被使用。

使用f-strings的全部意义在于提高代码的可读性。用f-字符串可以做的事情没有一个是你不能用 format 做的。仔细考虑一下是否有什么 可读性更强 关于这一点(如果你能做到的话)。

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

...or this:

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

...or this:

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

vs. this:

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

最后一种方式至少是可读的,如果不是更多的话。

简而言之:当你需要螺丝刀时,不要因为你有一把闪亮的新螺丝刀就用锤子。代码被阅读的次数远远多于被书写的次数。

对于其他用例,是的,有可能chr(10)的想法或newline的想法可能是合适的。但是,对于所给的那个案例,就不合适了。

可读性是主观的 :)......旧的做法适合熟练的人,在某些情况下可以更有可读性,但对新手来说几乎是未知的,因此他们无法阅读。对不起,我的观点是哲学性的。
@malmed 可读性通常不是主观的。在这种情况下肯定不是。但这并不值得长时间争论。
@malmed 你是对的,可读性是 "主观的",因为它是 可培训 通过先前的经验。但是,由于我们的大脑和感官有局限性,可读性可以从以下方面进行客观衡量:扫描相关文本在物理上有多容易,人类大脑倾向于正确的模式匹配有多频繁,它对我们的大脑对其他代码的预测有多正确(包括语句/行的开头暗示了结尾会是什么),以及它对新手来说有多容易变得更容易阅读。
CrackerKSR
CrackerKSR
发布于 2021-10-29
0 人赞同
print(f'{"blah\n"}')

上述语句将引发SyntaxError。 但是为了避免这个错误,你可以简单地将包含\n的字符串分配给一个变量,并在f-string中使用它。

x = "blah\n"
print(f'{x}')
    
Bill Stratton
Bill Stratton
发布于 2021-10-29
0 人赞同

如果(而且只有在!)可读性是最重要的,而且速度确实不是一个因素,那么f-字符串是非常有用的,它可以使一个简单的函数自我记录,即使有更简单的方法来编程。在以下情况下,使用f-strings可以最大限度地提高可读性。(1)改变参数状态的语句是明显的,(2)当参数被打印出来时,打印语句的格式是精心设计的,并以视觉方式呈现,使参数突出出来。

function to print out an identification header, consisting of the programmer supplied title, lastname, and firstname: FORMAT_DATE = "%m-%d-%y %H:%M:%S" date_and_time = datetime.now() name_line = f"* {lastname}, {firstname}" title_line = f"* {title}" date_line = f"* {date_and_time.strftime(FORMAT_DATE)}" print(name_line + '\n' + title_line + '\n' + date_line)