【问题标题】:How to use newline '\n' in f-string to format output in Python 3.6?如何在 f-string 中使用换行符 '\n' 来格式化 Python 3.6 中的输出?
【发布时间】:2023-04-04 23:34:02
【问题描述】:

我想知道如何使用 f-strings 以 Pythonic 方式格式化这个案例:

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

问题在于 '\' 不能在 f 字符串的 {...} 表达式部分中使用。 预期输出:

Winners are:
Adam
Bob
Cyril

【问题讨论】:

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

标签: python python-3.x newline python-3.6 f-string


【解决方案1】:

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

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

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

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

一个选项是将'\n' 分配给一个名称,然后在f-string 中分配.join;也就是说,不使用文字:

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-strings 和str.format 之间的细微差别之一。在后者中,您始终可以使用标点符号,前提是已解压缩包含这些键的相应古怪字典:

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

(请不要这样做。)

在前者中,标点符号是不允许的,因为您不能拥有使用它们的标识符。


除此之外:我肯定会选择printformat,因为其他答案建议作为替代方案。我给出的选项仅在您出于某种原因必须使用 f 字符串时才适用。

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

【讨论】:

  • 对我来说没有意义:nl = '\n' text = f"Winners are:{nl}"。使用:text = f"获胜者是:\n"
  • @Timo OP 需要 join on \n 在格式字符串中,特别是在嵌入表达式中。
  • 我相信@timo 的观点是第一个{nl} 不是必需的,因为\n 不在f 字符串的表达式部分中。 text = f"Winners are:\n" 非常好,是 {"\n".join()} 部分导致 f 字符串出现问题。
【解决方案2】:

您不需要 f-strings 或其他格式化程序来打印带有分隔符的字符串列表。只需将sep 关键字参数用于print()

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

输出:

Winners are:
Adam
Bob
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: 然后使用str.join(): text = '\n'.join(['Winners are:', *names])。顺便说一句,print() 可用于写入 任何文件(使用 file 参数指定,默认为 sys.stdout)。
【解决方案3】:

其他答案提供了如何将换行符放入 f 字符串字段的想法。但是,我会争辩说,对于 OP 给出的示例(可能表示或可能不表示 OP 的实际用例),实际上不应使用这些想法。

使用 f-strings 的全部意义在于提高代码的可读性。对 f-strings 没有什么是你不能用 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 想法可能是合适的。但不是给定的。

【讨论】:

  • 可读性是主观的 :) ...旧的做法适合熟练的人,并且在某些情况下可能更具可读性,但对于新手来说几乎是未知的,因此对他们来说是不可读的。抱歉哲学观点。
  • @malmed 可读性通常不是主观的。在这种情况下绝对不是。但这不值得争论。
  • @malmed 你说得对,可读性是“主观的”,因为它可以通过先前的经验训练。但由于我们的大脑和感官有局限性,可读性可以客观地衡量,包括扫描相关文本的物理容易程度、人类大脑倾向于正确匹配文本的频率、它暗示我们的大脑预测其他内容的正确程度代码(包括提示结尾的语句/行的开头),以及它对新手来说变得更具可读性的难易程度。
【解决方案4】:

您不能像其他人所说的那样在 f 字符串中使用反斜杠,但您可以使用 os.linesep 绕过这个问题(尽管请注意这在所有平台上都不是 \n,除非阅读/写二进制文件;见Rick'scmets):

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

【讨论】:

  • 不是我,但在编写文本时使用os.linesepnot a good idea
  • @RickTeachey 我确实已经在括号中添加了警告并提出了另一种方法。无论如何,OP 正在打印到屏幕,而不是写入以文本模式打开的文件
  • 我认为这不重要。 os.linesep 只是 for reading, or reading and writing in binary mode。我知道在这种情况下它会起作用,但这是一个坏习惯。但同样:我不是反对者。警告对我来说已经足够好了。 :)
【解决方案5】:
print(f'{"blah\n"}')

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

x = "blah\n"
print(f'{x}')

【讨论】:

    【解决方案6】:

    如果(且仅当!)可读性是重中之重,而速度确实不是一个因素,即使有更简单的编程方法,f-strings 对于使简单的函数自我记录也非常有用。在以下情况下,使用 f 字符串可以最大限度地提高可读性:(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)
    

    输出:

    * Lovelace, Ada
    * Bernoulli Numbers algorithm implemented in Python
    * 10-28-42 20:13:22
    

    【讨论】:

      猜你喜欢
      • 2017-09-15
      • 1970-01-01
      • 1970-01-01
      • 2023-02-16
      • 2022-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多