16

So I've got a function which creates a little star table based on some data collected elsewhere in the program. While the table produces the correct output, since the number of characters in each number changes, it un-aligns the table. For example,

70-78: *****
79-87: ***
88-96: ****
97-105: **
106-114: ******
115-123: ****

Is there any way to make the stars align (hehe) so that the output is something like this:

70-78:   *****
79-87:   ***
88-96:   ****
97-105:  **
106-114: ******
115-123: ****

Here's how I currently print the table.

for x in range(numClasses):
    print('{0}-{1}: {2}'.format(lower[x],upper[x],"*"*num[x]))
4

5 回答 5

14

str.format已经有可能指定对齐方式。您可以使用{0:>5}; 这会将参数0向右对齐 5 个字符。然后,我们可以使用平均显示所有数字所需的最大位数动态构建格式字符串:

>>> lower = [70, 79, 88, 97, 106, 115]
>>> upper = [78, 87, 96, 105, 114, 123]
>>> num = [5, 3, 4, 2, 6, 4]
>>> digits = len(str(max(lower + upper)))
>>> digits
3
>>> f = '{0:>%d}-{1:>%d}: {2}' % (digits, digits)
>>> f
'{0:>3}-{1:>3}: {2}'
>>> for i in range(len(num)):
        print(f.format(lower[i], upper[i], '*' * num[i]))

 70- 78: *****
 79- 87: ***
 88- 96: ****
 97-105: **
106-114: ******
115-123: ****

实际上,您甚至可以在此处使用带有嵌套字段的单个格式字符串:

>>> for i in range(len(num)):
        print('{0:>{numLength}}-{1:>{numLength}}: {2}'.format(lower[i], upper[i], '*' * num[i], numLength=digits))
于 2013-06-13T17:21:29.573 回答
10

这应该可以解决问题。我认为有一些聪明的方法。

print '70-78:'.ljust(10) + '*****'

你也可以使用expandtabs()

print ('70-78'+'\t'+ '*****').expandtabs(10)
于 2013-06-13T15:55:14.470 回答
1

好的,虽然我正在使用的解决方案无疑是临时的,但它的工作原理和规模比迄今为止的答案更好。基本上这只是 VR17 建议的方法,但要多一点,以便标签大小随数据集缩放,而不仅仅是硬编码。

首先,我创建了一个返回某个数字中的数字字符的方法。

def charNum(number):
    return math.floor(math.log(number,10)+1)

然后我在我的和数据集charNum()的最后一点上使用了这个函数。每个列表只需要使用最后一点,因为最后一点是最大的数字。然后我计算了不是数字的字符(破折号、分号和空格),并进行了相应的调整。 所以最终的 tabLength 变量如下所示:lowerupper

tabLength = charNum(lower[-1])+charNum(upper[-1])+3

然后我将tabLength变量插入expandTab()函数以获得适当的间距。这是一些示例输出:

1-11:  *******
12-22: *
23-33: ***
34-44: **
45-55: ***
56-66: *

99-249:   *****
250-400:  ****
401-551:  **
552-702:  **
703-853:  *
854-1004: ***

99-200079:      ******
200080-400060:  **
400061-600041:  ****
600042-800022:  **
800023-1000003: *

我真正能看到的唯一问题是,如果我想将其扩展为表格或其他东西,这些选项卡都会很时髦。如果我这样做了,我可能会调查ljust并且rjust我现在还不太熟悉。我会把这个问题留一会儿,以防有人提出更好的答案。

于 2013-06-13T17:11:20.420 回答
1
lower = [70, 79, 88, 97, 106]
upper = [78, 87, 105, 114, 123]
num = [5, 3, 4, 2, 6, 4]

for l, u, n in zip(lower, upper, num):
    print('{0:<9} {1}'.format('{0}-{1}:'.format(l, u), '*' * n))

http://docs.python.org/3/library/string.html#format-specification-mini-language

于 2013-06-13T16:11:04.023 回答
0

简单的方法(在您的情况下)是放置一个制表符而不是空格:

for x in range(numClasses):
    print('{0}-{1}:\t{2}'.format(lower[x],upper[x],"*"*num[x]))

另一种方法是使用str.ljust

for x in range(numClasses):
    label = '{0}-{1}:'.format(lower[x], upper[x])
    print(label.ljust(10, ' ') + "*" * num[x])
于 2013-06-13T16:03:29.567 回答