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

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

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

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

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

Winners are:
Adam
Bob
Cyril

I would like to know how to format this case in a Pythonic way with f-strings:

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

The problem is that '\' cannot be used inside the {...} expression portions of an f-string. Expected output:

Winners are:
Adam
Bob
Cyril

回答 0

你不能 反斜杠不能出现在花括号内{};这样做会导致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字符串的情况下适用。

仅仅因为有些新事物,并不意味着您应该尝试用它做一切;-)

You can’t. Backslashes cannot appear inside the curly braces {}; doing so results in a SyntaxError:

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

This is specified in the PEP for f-strings:

Backslashes may not appear inside the expression portions of f-strings, […]

One option is assinging '\n' to a name and then .join on that inside the f-string; that is, without using a literal:

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

Results in:

Winners are:
Adam
Bob
Cyril

Another option, as specified by @wim, is to use chr(10) to get \n returned and then join there. f"Winners are:\n{chr(10).join(names)}"

Yet another, of course, is to '\n'.join beforehand and then add the name accordingly:

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

which results in the same output.

Note:

This is one of the small differences between f-strings and str.format. In the latter, you can always use punctuation granted that a corresponding wacky dict is unpacked that contains those keys:

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

(Please don’t do this.)

In the former, punctuation isn’t allowed because you can’t have identifiers that use them.


Aside: I would definitely opt for print or format, as the other answers suggest as an alternative. The options I’ve given only apply if you must for some reason use f-strings.

Just because something is new, doesn’t mean you should try and do everything with it ;-)


回答 1

您不需要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)))

You don’t need f-strings or other formatters to print a list of strings with a separator. Just use the sep keyword argument to print():

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

Output:

Winners are:
Adam
Bob
Cyril

That said, using str.join()/str.format() here would arguably be simpler and more readable than any f-string workaround:

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

回答 2

您不能像其他人所说的那样在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

You can’t use backslashes in f-strings as others have said, but you could step around this using os.linesep (although note this won’t be \n on all platforms, and is not recommended unless reading/writing binary files; see Rick’s comments):

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

Or perhaps in a less readable way, but guaranteed to be \n, with chr():

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

回答 3

其他答案给出了有关如何将换行符放入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想法可能是适当的。但不是给定的。

The other answers give ideas for how to put the newline character into a f-string field. However, I would argue that for the example the OP gave (which may or may not be indicative of OP’s actual use case), none of these ideas should actually be used.

The entire point of using f-strings is increasing code readability. There is nothing you can do with f-strings that you cannot do with format. Consider carefully whether there is anything more readable about this (if you could do it):

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))

The last way is at least as readable, if not more so.

In short: don’t use a hammer when you need a screwdriver just because you have a shiny new one. Code is read much more often than it is written.

For other use cases, yes, it’s possible the chr(10) idea or newline idea may be appropriate. But not for the one given.