如何在f字符串中使用换行符'\ n'格式化Python 3.6中的输出?


109

我想知道如何用f字符串以Pythonic方式格式化这种情况:

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

问题是'\'无法在{...}f字符串的表达式部分内使用。预期产量:

Winners are:
Adam
Bob
Cyril

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

Answers:


123

你不能 反斜杠不能出现在花括号内{};这样做会导致SyntaxError

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

这是在PEP中为f字符串指定的:

反斜杠可能不会出现在f字符串的表达式部分内,[...]

一种选择是先'\n'命名,然后再.joinf-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)}"

当然,还有另一种方法是'\n'.join预先添加相应的名称:

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

结果相同。

注意:

这是f-string和之间的细微差别之一str.format。在后者中,您可以始终使用标点符号,只要打开包含这些键的相应古怪字典即可:

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

(请不要这样做。)

在前一种情况下,标点符号是不允许的,因为您不能使用它们的标识符。


撇开:我肯定会选择printformat,因为其他答案也可以替代。我给出的选项仅在由于某些原因必须使用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(*dir(some_object), sep='\n')或)的内部print(*vars(some_object), sep='\n')
里克

1
如果您不想直接打印列表,例如将其传递给记录器,该怎么办?
bob

1
@bob:然后使用str.join()text = '\n'.join(['Winners are:', *names])。BTW,print()可用于写入任何文件(默认情况下使用file参数指定sys.stdout)。
Eugene Yarmash

10

您不能像其他人所说的那样在f字符串中使用反斜杠,但是您可以使用来解决这个问题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不是一个好主意写文字的时候。
里克

1
@RickTeachey我已经在括号中添加了警告,并提出了另一种方法。无论如何,OP正在打印到屏幕上,而不是写入以文本模式打开的文件
Chris_Rands

我认为没关系。os.linesep用于以二进制方式读取或读写。我知道在这种情况下也可以使用,但是这是一个不好的习惯。但是再说一遍:我不是不赞成投票的人。警告对我来说足够好了。:)
瑞克(Rick)支持莫妮卡(Monica)

6

其他答案给出了有关如何将换行符放入f字符串字段的想法。但是,我认为对于OP给出的示例(可能指示OP的实际用例),实际上不应该使用这些想法。

使用f字符串的全部目的是提高代码的可读性。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
可读性是主观的:) ...旧的做法适合熟练的人,在某些情况下可读性更好,但是对于菜鸟来说几乎是未知的,因此对他们来说是不可读的。对不起,从哲学的角度来看。
malmed

2
@malmed可读性通常不是主观的。绝对不是这种情况。但这不值得详细讨论。
瑞克(Rick)

@malmed是对的,因为可读性是可以根据先前的经验进行训练的,所以它是“主观的” 。但是由于我们的大脑和感官有局限性,因此可以通过以下方式客观地衡量可读性:扫描相关文本在物理上有多容易,人类大脑多久倾向于正确地对其进行模式匹配,它如何正确暗示我们对其他大脑的预测代码(包括一条语句/行的开头,提示结尾),以及它对新手的可读性。
mtraceur
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.