格式化输出字符串,右对齐
Posted
技术标签:
【中文标题】格式化输出字符串,右对齐【英文标题】:Format output string, right alignment 【发布时间】:2012-01-04 06:54:37 【问题描述】:我正在处理一个包含坐标 x、y、z 的文本文件
1 128 1298039
123388 0 2
....
每一行被分隔成3个项目使用
words = line.split()
处理数据后,我需要将坐标写回到另一个 txt 文件中,以便每列中的项目右对齐(以及输入文件)。每一行都是由坐标组成的
line_new = words[0] + ' ' + words[1] + ' ' words[2].
C++ 中是否有像std::setw()
之类的操纵器允许设置宽度和对齐方式?
【问题讨论】:
【参考方案1】:这是另一种使用“f-string”格式进行格式化的方法:
print(
f"'Trades:':<15cnt:>10",
f"\n'Wins:':<15wins:>10",
f"\n'Losses:':<15losses:>10",
f"\n'Breakeven:':<15evens:>10",
f"\n'Win/Loss Ratio:':<15win_r:>10",
f"\n'Mean Win:':<15mean_w:>10",
f"\n'Mean Loss:':<15mean_l:>10",
f"\n'Mean:':<15mean_trd:>10",
f"\n'Std Dev:':<15sd:>10",
f"\n'Max Loss:':<15max_l:>10",
f"\n'Max Win:':<15max_w:>10",
f"\n'Sharpe Ratio:':<15sharpe_r:>10",
)
这将提供以下输出:
Trades: 2304
Wins: 1232
Losses: 1035
Breakeven: 37
Win/Loss Ratio: 1.19
Mean Win: 0.381
Mean Loss: -0.395
Mean: 0.026
Std Dev: 0.56
Max Loss: -3.406
Max Win: 4.09
Sharpe Ratio: 0.7395
你在这里所做的是你说第一列是 15 个字符长,它是左对齐的,第二列(值)是 10 个字符长,它是右对齐的。
如果您加入列表中的项目,并且想要格式化项目之间的空间,您可以使用 `` 和常规格式化技术。
此示例将每个数字用 3 个空格分隔。这里的关键是 f"'':>3"
print(f"'':>3".join(str(i) for i in range(1, 11)))
输出:
1 2 3 4 5 6 7 8 9 10
【讨论】:
有没有办法对格式的宽度进行参数化?在此示例中,如果您决定将格式更改为 20 和 15 宽度,则需要更改多行。widths = [15, 10]
f"'Trades:':<width[0]cnt:>width[1]",
我想实现上面那样的东西。
知道了!也许有人会发现它有帮助。为此,我还需要一个嵌套括号:f"'Trades:':<width[0]cnt:>width[1]"
有时最好的答案是那些没有回答确切问题的答案。谢谢你! :)
@BrianWiley 没错!我也在寻找格式化字符串文字。我总是忘记“string-in-string” hack(即在 ` " " ` 中使用 ` ' ' `)。【参考方案2】:
将 Vlad 的精彩内容与其他内容混合,也可以编写代码以实现可读性和易用性,例如 ...
>>> cnt = wins = losses = str( 2)
>>> evens = win_r = mean_w = str( 14)
>>> mean_l = mean_trd = sd = str( 336)
>>> max_l = max_w = sharpe_r = str(4278)
>>>
>>> rpad = 10
>>>
>>> print(
... '\n Trades ' + cnt.rjust(rpad),
... '\n Wins ' + wins.rjust(rpad),
... '\n Losses ' + losses.rjust(rpad),
... '\n Breakeven ' + evens.rjust(rpad),
... '\n Win/Loss Ratio ' + win_r.rjust(rpad),
... '\n Mean Win ' + mean_w.rjust(rpad),
... '\n Mean Loss ' + mean_l.rjust(rpad),
... '\n Mean ' + mean_trd.rjust(rpad),
... '\n Std Dev ' + sd.rjust(rpad),
... '\n Max Loss ' + max_l.rjust(rpad),
... '\n Max Win ' + max_w.rjust(rpad),
... '\n Sharpe Ratio ' + sharpe_r.rjust(rpad),
... )
Trades 2
Wins 2
Losses 2
Breakeven 14
Win/Loss Ratio 14
Mean Win 14
Mean Loss 336
Mean 336
Std Dev 336
Max Loss 4278
Max Win 4278
Sharpe Ratio 4278
【讨论】:
【参考方案3】:通过使用 f-string 并控制尾随数字的数量来做到这一点:
print(f'A number -> my_number:>20.5f')
【讨论】:
【参考方案4】:我真的很喜欢 Python 3.6+ 中的新文字字符串插值:
line_new = f'word[0]:>12 word[1]:>12 word[2]:>12'
参考:PEP 498 -- Literal String Interpolation
【讨论】:
【参考方案5】:使用较新的str.format
syntax 尝试这种方法:
line_new = ':>12 :>12 :>12'.format(word[0], word[1], word[2])
下面是使用旧的%
语法的方法(适用于不支持str.format
的旧版Python):
line_new = '%12s %12s %12s' % (word[0], word[1], word[2])
【讨论】:
请注意“旧”语法如何更简洁、更易于阅读和更短。 我想我会添加一个比提供的链接更直接的链接:docs.python.org/2/library/… 肯定更短,我不知道清洁剂的真正含义,但我认为“更易于阅读”只是因为它很熟悉。如果您还不熟悉其中之一,那么新格式似乎更易于阅读。用于字符串格式化的“.format”当然看起来比百分比/模数更直观。右对齐的右箭头似乎也很直观。 @Mark 一种更简洁的旧方法是使用更少的字符。是的,熟悉的新方法变得直观,但它并不干净和简单。对于那些习惯于通过古老的 C 语言(一种具有模范简洁性和精确性的语言)带给我们的语法的人来说,旧方法更直观。新方式有什么先例? @StephenBoston 我将把可读性留给专家,但新方法绝对更干净。 Parens 不再是可选的。 % 可能会与数学运算符混淆(尽管在上下文中不太可能,但一目了然)。如果 word[n] 不是预期的类型(在这种情况下为字符串),旧方法将失败。新方法不需要知道传入的类型是什么,它总是有效的。干净简单。说句公道话,我对 printf 风格并不满意(我主要是用 cout 做 C 语言)。【参考方案6】:输出的简单列表:
a = 0.3333333
b = 200/3
print("variable a variable b")
print("%10.2f %10.2f" % (a, b))
输出:
variable a variable b
0.33 66.67
%10.2f: 10 是最小长度,2 是小数位数。
【讨论】:
【参考方案7】:你可以这样对齐:
print(':>8 :>8 :>8'.format(*words))
其中>
表示“右对齐”,8
是特定值的宽度。
这是一个证明:
>>> for line in [[1, 128, 1298039], [123388, 0, 2]]:
print(':>8 :>8 :>8'.format(*line))
1 128 1298039
123388 0 2
附言。 *line
表示line
列表将被解包,因此.format(*line)
的工作方式与.format(line[0], line[1], line[2])
类似(假设line
是一个只有三个元素的列表)。
【讨论】:
【参考方案8】:可以通过rjust
实现:
line_new = word[0].rjust(10) + word[1].rjust(10) + word[2].rjust(10)
【讨论】:
以上是关于格式化输出字符串,右对齐的主要内容,如果未能解决你的问题,请参考以下文章