2009-06-22 87 views
8

这个应该是很容易。Python中的十进制对齐格式化

这里是我的阵列(更确切地说,产生代表测试阵列的方法):

>>> ri = numpy.random.randint 
>>> ri2 = lambda x: ''.join(ri(0,9,x).astype('S')) 
>>> a = array([float(ri2(x)+ '.' + ri2(y)) for x,y in ri(1,10,(10,2))]) 
>>> a 
array([ 7.99914000e+01, 2.08000000e+01, 3.94000000e+02, 
     4.66100000e+03, 5.00000000e+00, 1.72575100e+03, 
     3.91500000e+02, 1.90610000e+04, 1.16247000e+04, 
     3.53920000e+02]) 

我想一个字符串列表,其中“\ n'.join(list_o_strings)将打印:

79.9914 
    20.8 
    394.0 
4661.0 
    5.0 
1725.751 
    391.5 
19061.0 
11624.7 
    353.92 

我想垫左边的的权利(但没有超过必要的)。

我想要一个十进制后的零,如果这是十进制后的所有。

我不想科学记数法。

..我不想失去任何有效数字。 (在353.98000000000002 2不显著)

是啊,这是很好的希望..

的Python 2.5的%g, %fx.x等要么令人迷惑我,或者不能做到这一点。 我还没有试过import decimal呢。我看不到NumPy做,要么(虽然,在​​和array.__repr__是小数对齐(但有时返回科学)。

哦,速度计数。我在这里处理的大阵列。

我的当前的解决方案的方法是:( '')

  1. 到STR(a)和所述阵列和分割在解析关闭NumPy的的括号
  2. 为str(e)中的每个元素然后垫和重建
  3. 到a.astype('S'+ str(i))其中i是最大值(len(str(a))),那么pad

看起来应该有一些现成的解决方案有...(但不要求)

顶部的建议失败时dtype是float64:

>>> a 
array([ 5.50056103e+02, 6.77383566e+03, 6.01001513e+05, 
     3.55425142e+08, 7.07254875e+05, 8.83174744e+02, 
     8.22320510e+01, 4.25076609e+08, 6.28662635e+07, 
     1.56503068e+02]) 
>>> ut0 = re.compile(r'(\d)0+$') 
>>> thelist = [ut0.sub(r'\1', "%12f" % x) for x in a] 
>>> print '\n'.join(thelist) 
    550.056103 
6773.835663 
601001.513 
355425141.8471 
707254.875038 
    883.174744 
    82.232051 
425076608.7676 
62866263.55 
    156.503068 
+0

请发布不起作用的代码。 – 2009-06-22 10:50:31

回答

9

很抱歉,但深入调查后,我无法找到任何方式来执行所需的任务没有最少的后期处理(去掉你不想看到的尾随零);是这样的:

import re 
ut0 = re.compile(r'(\d)0+$') 

thelist = [ut0.sub(r'\1', "%12f" % x) for x in a] 

print '\n'.join(thelist) 

是快速,简洁,但休息的是“现成的现成”的约束 - 这是,相反,一般格式的模块化组合(这几乎是你想要做什么,不过有叶子尾随零你想隐藏)和RE去除不希望的尾随零。实际上,我认为它完全符合你的要求,但我相信你所陈述的条件是过度限制的。

编辑:原来的问题是编辑指定更显著的数字,需要超越什么需要的最大数量没有多余的前导空格,并提供了一个新的例子(我以前的建议下,上述不匹配所需输出)。删除一堆字符串中常见的主要空白字符的工作最好使用textwrap.dedent来执行 - 但是它适用于单个字符串(带有换行符),而所需输出是字符串列表。没问题,我们只是把线一起,他们迪登,并再次分裂:

import re 
import textwrap 

a = [ 5.50056103e+02, 6.77383566e+03, 6.01001513e+05, 
     3.55425142e+08, 7.07254875e+05, 8.83174744e+02, 
     8.22320510e+01, 4.25076609e+08, 6.28662635e+07, 
     1.56503068e+02] 

thelist = textwrap.dedent(
     '\n'.join(ut0.sub(r'\1', "%20f" % x) for x in a)).splitlines() 

print '\n'.join(thelist) 

发出:

 550.056103 
    6773.83566 
    601001.513 
355425142.0 
    707254.875 
     883.174744 
     82.232051 
425076609.0 
62866263.5 
     156.503068 
+0

我无法保证%12f不会丢失有效数字。 (我做了一个编辑,并改变了我的测试数组的生成方式以反映这一点。)如果我增加到20%或更多以保证这一点,那么左侧会有太多的填充。 (想要最大的价值没有领先的空间)我也会拿回柜子的解决方案! – Paul 2009-06-22 05:56:12

2

蟒蛇字符串格式化既可以只打印出所需的小数(带%g)或使用一组固定的小数(使用%f)。但是,您只想打印出必要的小数,除非数字是整数,那么您需要一位小数,这使得它很复杂。

这意味着你最终会喜欢的东西:

def printarr(arr): 
    for x in array: 
     if math.floor(x) == x: 
      res = '%.1f' % x 
     else: 
      res = '%.10g' % x 
     print "%*s" % (15-res.find('.')+len(res), res) 

这将首先创建一个字符串或者带1位小数,如果该值是一个整数,或者它会自动小数打印(但只最多10个数字),如果它不是分数。最后,它将打印它,调整,以便小数点将对齐。

尽管如此,numpy实际上可以做你想做的事,因为如果它太长,你通常会希望它处于指数模式。