【问题标题】:Using Python's Format Specification Mini-Language to align floats使用 Python 的 Format Specification Mini-Language 对齐浮点数
【发布时间】:2012-03-03 19:20:33
【问题描述】:

我读到我可以使用 Python 的 Format Specification Mini-Language 来更好地控制字符串的显示方式。但是,我很难弄清楚如何使用它来显示在小数点上对齐的浮点数。

例如,假设我有以下三个列表:

job_IDs = ['13453', '123', '563456'];
memory_used = [30, 150.54, 20.6];
memory_units = ['MB', 'GB', 'MB'];

我想遍历这三个列表并打印

Job 13453:   30      MB
Job 123:    150.54   MB
Job 563456:  20.6    GB

到目前为止我已经尝试过:

for i in range(len(jobIDs)):
   my_str = "{item:15}{value:6} {units:3}".format( 
   item='Job ' + job_IDs[i] + ':' , value=str(memories[i]),units=memory_units[i]);

   print my_str

哪个打印:

Job 13453:   30      MB
Job 123:     150.54  MB
Job 563456:  20.6    GB

这几乎是正确的,但它不会围绕小数点对齐浮点数。如何使用 Python 的 Format Specification Mini-Language 按我需要的方式进行操作?

【问题讨论】:

  • 您的memory_used 列表是一个字符串列表。通常,当您想以格式化方式打印浮点数时,您将使用浮点数。您现在拥有的是一组字符串,并且您希望格式能够理解它应该被特殊对待。但也许这只是您在此处发布的代码?
  • 感谢@MattiasNilsson 我已经相应地更新了我的代码。

标签: python string mini-language


【解决方案1】:

这就是你想要的:

for i in range(len(job_IDs)):
    print "Job {item:15} {value[0]:>6}.{value[1]:<6} {units:3}".format(item=job_IDs[i]+':', value=memory_used[i].split('.') if '.' in memory_used[i] else (memory_used[i], '0'), units=memory_units[i])

这是它的工作原理:

这是主要部分:value=memory_used[i].split('.') if '.' in memory_used[i] else (memory_used[i], '0'),意思是:如果有小数点,将字符串整体和小数部分拆分,或者将小数部分设置为0。

然后在格式字符串中:{value[0]:&gt;6}.{value[1]:&lt;6} 表示,整个部分右移,后跟一个点,然后小数部分左移。

哪个打印:

Job 13453:              30.0      MB
Job 123:               150.54     GB
Job 563456:             20.6      MB

【讨论】:

  • 谢谢@xiaomao。我从未见过要执行的命令出现在条件 before 的 if 语句。你有什么指示我可以阅读更多关于这方面的信息吗?还有,数字6在格式字符串value[0]:&lt;6中的作用是什么?
  • @roseck python 的 ?:-style 语法是 (true) if (condition) else (false)&lt;6 中的 &lt; 左移,6 填充为 6 个字符。
  • -1:实际上,如果memory_used 是整数和浮点数的列表,如 OP 的问题所示,这不起作用。如果是,则出现TypeError: argument of type 'int' is not iterable
【解决方案2】:

这是另一个基于.split('.') 想法的实现。它可能更具可读性。在'.'上拆分,左对齐,右对齐:

width = max(map(len, job_IDs)) # width of "job id" field 
for jid, mem, unit in zip(job_IDs, memory_used, memory_units):
  print("Job {jid:{width}}: {part[0]:>3}{part[1]:1}{part[2]:<3} {unit:3}".format(
    jid=jid, width=width, part=str(mem).partition('.'), unit=unit))

Output

Job 13453 :  30     MB 
Job 123   : 150.54  GB 
Job 563456:  20.6   MB 

【讨论】:

    【解决方案3】:

    如果有帮助,我使用了一个类似的功能:

    def align_decimal(number, left_pad=7, precision=2):
        """Format a number in a way that will align decimal points."""
        outer = '{0:>%i}.{1:<%i}' % (left_pad, precision)
        inner = '{:.%if}' % (precision,)
        return outer.format(*(inner.format(number).split('.')))
    

    它允许小数点后的固定精度。

    【讨论】:

      【解决方案4】:

      这样做:

      import re
      
      job_IDs = ['13453', '123', '563456']
      memory_used = ['30', '150.54', '20.6']
      memory_units = ['MB', 'GB', 'MB']
      
      for i in range(len(job_IDs)):
          lh=re.match(r'(\d+)',memory_used[i]).group(1)
          if '.' in memory_used[i]:
              rh=re.match(r'(\d+)\.(\d+)',memory_used[i]).group(2)
              sep='.'
          else:
              rh=''    
              sep=' '
      
      
          my_str = "{item:15}{l:>6}{s:1}{r:6} {units:3}".format( 
          item='Job ' + job_IDs[i] + ':' , l=lh,s=sep,r=rh,units=memory_units[i])
      
          print my_str
      

      要获得准确的输出,您需要断开可选“。”上的字符串

      您还可以将这些字符串转换为浮点数。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-03-20
        • 1970-01-01
        • 2014-11-05
        • 2015-03-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-08
        相关资源
        最近更新 更多