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

mal*_*med 57 python newline python-3.x python-3.6 f-string

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

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

问题是'\'不能在f-string中使用.预期产量:

Winners are:
Adam
Bob
Cyril
Run Code Online (Sandbox Code Playgroud)

Jim*_*ard 65

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

>>> f'{\}'
SyntaxError: f-string expression part cannot include a backslash
Run Code Online (Sandbox Code Playgroud)

这在FEP中为f字符串指定:

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

一种选择是'\n'在一个名称上,然后.joinf-string 内部; 也就是说,不使用文字:

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

结果是:

Winners are:
Adam
Bob
Cyril
Run Code Online (Sandbox Code Playgroud)

另一种选择,如@wim规定,就是用chr(10)得到\n恢复,然后加入那里.f"Winners are:\n{chr(10).join(names)}"

当然,另一个是'\n'.join事先,然后相应地添加名称:

n = "\n".join(names)
text = f"Winners are:\n{n}"
Run Code Online (Sandbox Code Playgroud)

这导致相同的输出.

注意:

这是f-strings和str.format.之间的一个小差异.在后者中,您总是可以使用标点符号来解释包含这些键的相应古怪dict的解包:

>>> "{\\} {*}".format(**{"\\": 'Hello', "*": 'World!'})
"Hello World!"
Run Code Online (Sandbox Code Playgroud)

(请不要这样做.)

在前者中,不允许使用标点符号,因为您不能使用标点符号.


旁白:我肯定会选择print或者format,正如其他答案所暗示的那样.我给出的选项仅适用于因某些原因必须使用f-strings的情况.

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


Eug*_*ash 33

您不需要f字符串或其他格式化程序来使用分隔符打印字符串列表.只需将sep关键字参数传递给print():

names = ['Adam', 'Bob', 'Cyril']
print("Winners are:", *names, sep="\n")
Run Code Online (Sandbox Code Playgroud)

输出:

Winners are:
Adam
Bob
Cyril
Run Code Online (Sandbox Code Playgroud)

也就是说,使用str.format()这里可以说比任何f-string解决方案更简单,更易读:

print("Winners are:\n{}".format("\n".join(names))
Run Code Online (Sandbox Code Playgroud)

  • 到目前为止最佳答案.这些天我一直在打印函数中使用星形解包来查看某个对象,例如`print(*dir(some_object),sep ='\n')`或`print(*vars(some_object),sep = '\n')`. (9认同)
  • 如果您不想直接打印列表(例如将其传递给记录器),该怎么办? (2认同)

Chr*_*nds 18

您不能像其他人所说的那样在 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 
Run Code Online (Sandbox Code Playgroud)

或者也许以一种不太可读的方式,但保证是\n,与chr()

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

  • 不是我,但是在编写文本时使用 `os.linesep` [不是一个好主意](https://docs.python.org/3/library/os.html?highlight=linesep#os.linesep)。 (2认同)

Ric*_*ica 6

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

使用f字符串的全部意义在于提高代码的可读性.你无法用f字符串做任何事情format.仔细考虑是否有更多可读性(如果你能做到的话):

f"Winners are:\n{'\n'.join(names)}"
Run Code Online (Sandbox Code Playgroud)

...或这个:

newline = '\n'
f"Winners are:\n{newline.join(names)}"
Run Code Online (Sandbox Code Playgroud)

...或这个:

"Winners are:\n{chr(10).join(names)}"
Run Code Online (Sandbox Code Playgroud)

与此:

"Winners are:\n{}".format('\n'.join(names))
Run Code Online (Sandbox Code Playgroud)

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

简而言之:当你需要一把螺丝刀时,不要因为你有一个闪亮的新螺丝刀而使用锤子.代码的读取频率远高于编写代码.

对于其他用例,是的,这个chr(10)想法或newline想法可能是合适的.但不是给定的.

  • 可读性是主观的:) ...旧的练习适合熟练的,并且在某些情况下可以更具可读性,但对于新手来说几乎是不可知的,因此对它们来说是不可读的.抱歉,哲学观点. (5认同)
  • @malmed可读性通常不是主观的。绝对不是这种情况。但这不值得详细讨论。 (2认同)

小智 5

在 Python 3.12 + 上,您可以

>>> names = ['Adam', 'Bob', 'Cyril']
>>> print(f"Winners are:\n{'\n'.join(names)}")
Winners are:
Adam
Bob
Cyril
Run Code Online (Sandbox Code Playgroud)

您还可以在 f 字符串的表达式部分中重复使用相同的引号:

>>> print(f"Winners are:\n{"\n".join(names)}")        
Winners are:
Adam
Bob
Cyril
Run Code Online (Sandbox Code Playgroud)

详细信息请参阅PEP 701