【问题标题】:How do I align text output in python?如何在python中对齐文本输出?
【发布时间】:2020-01-23 10:06:48
【问题描述】:

所以我有一个函数,它根据程序中其他地方收集的一些数据创建一个小星表。当表格产生正确的输出时,由于每个数字中的字符数发生变化,它会使表格不对齐。例如,

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

有没有什么办法可以让星星对齐(呵呵),让输出是这样的:

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

这是我目前打印表格的方式。

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

【问题讨论】:

    标签: python python-3.x


    【解决方案1】:

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

    【讨论】:

    • 旧字符串格式是在新字符串格式的大括号中嵌入变量值的唯一方法吗?
    • 不,你也可以在那里使用新的样式格式,但是你必须转义大括号,或者使用嵌套替换——我意识到这会更好,所以请参阅编辑在我的回答中:)
    • 只是为了澄清,为什么你必须设置数字等于它自己?您可以在 .format() 函数的其他地方使用已经定义的变量。
    • 是的,我选择的变量名并没有真正说明这一点(现在改了)。在numLength=digits 中,第一部分是命名参数名;第二部分是命名参数的值。所以digits=digits 会将函数的命名参数digits 设置为变量digits 的值。
    • @poke 我猜你的意思是最后一行的 numLength=digits。
    【解决方案2】:

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

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

    你也可以使用expandtabs()

    print ('70-78'+'\t'+ '*****').expandtabs(10)
    

    【讨论】:

    • 或者,以 OP 为例:print('{0}-{1}:\t{2}'.format(lower[x],upper[x],"*"*num[x]).expandtabs(10))
    【解决方案3】:
    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

    【讨论】:

      【解决方案4】:

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

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

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

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

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

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

      【讨论】:

        【解决方案5】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-08-06
          • 1970-01-01
          • 2022-01-07
          • 2022-01-11
          • 2017-05-22
          • 1970-01-01
          • 1970-01-01
          • 2020-04-12
          相关资源
          最近更新 更多