Python中的十进制对齐格式

Python中的十进制对齐格式,python,formatting,numpy,code-golf,Python,Formatting,Numpy,Code Golf,这应该很容易 这是我的数组(而是一种生成代表性测试数组的方法): 我想要一个字符串列表,其中'\n'.join(列表\o\u字符串)将打印: 79.9914 20.8 394.0 4661.0 5.0 1725.751 391.5 19061.0 11624.7 353.92 我想在左边和右边留出空间(但不超过必要的范围) 我想要小数点后的零,如果这是小数点后的全部内容 我不想要科学记数法 …我不想丢失任何有效数字。(在353.9800000000002中,

这应该很容易

这是我的数组(而是一种生成代表性测试数组的方法):

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

   79.9914
   20.8
  394.0
 4661.0
    5.0
 1725.751
  391.5
19061.0
11624.7
  353.92
我想在左边和右边留出空间(但不超过必要的范围)

我想要小数点后的零,如果这是小数点后的全部内容

我不想要科学记数法

…我不想丢失任何有效数字。(在353.9800000000002中,2不显著)

是的,很高兴想要

Python2.5的
%g,%fx.x
等要么让我迷惑,要么做不到。 我还没有尝试导入十进制。我也看不到这一点(尽管
数组.\uuuu str\uuuu
数组.\uuuu repr\uuuu
是十进制对齐的(但有时返回科学)

哦,速度很重要。我在处理大阵列

我目前的解决办法是:

  • str(a)并解析NumPy的括号
  • str(e)数组中的每个元素并拆分('.'),然后填充并重构
  • 到a.astype('S'+str(i)),其中i是最大值(len(str(a)),然后pad
  • 似乎应该有一些现成的解决方案…(但不是必需的)

    dtype
    为float64时,Top建议失败:

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

    很抱歉,经过彻底调查,我无法找到任何方法来执行您需要的任务,而不进行最低限度的后处理(去除您不希望看到的尾随零);例如:

    import re
    ut0 = re.compile(r'(\d)0+$')
    
    thelist = [ut0.sub(r'\1', "%12f" % x) for x in a]
    
    print '\n'.join(thelist)
    
    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)
    
    快速简洁,但打破了“现成”的限制——相反,它是通用格式的模块化组合(几乎可以实现您想要的功能,但留下要隐藏的尾随零)实际上,我认为这正是你所需要的,但我认为你所说的条件是过度约束的

    编辑:对原始问题进行了编辑,以指定更多的有效数字,不需要超出最大数字所需的额外前导空格,并提供了一个新示例(上面我先前的建议与所需输出不匹配)。删除一组字符串中常见的前导空格的工作最好使用--但这对单个字符串(使用换行符)有效,而所需的输出是字符串列表。没问题,我们只需将这些行放在一起,删除它们,然后再次拆分它们:

    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
    

    Pythons字符串格式既可以只打印必要的小数(使用%g),也可以使用固定的小数集(使用%f)。但是,您只需要打印必要的小数,除非数字是整数,那么您需要一个小数,这会使它变得复杂

    这意味着您最终会遇到以下情况:

    import re
    ut0 = re.compile(r'(\d)0+$')
    
    thelist = [ut0.sub(r'\1', "%12f" % x) for x in a]
    
    print '\n'.join(thelist)
    
    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实际上做了您想要的事情,因为如果它太长,您通常希望它处于指数模式。

    我不能保证%12f不会丢失有效数字。(我进行了编辑并更改了生成测试数组的方式以反映这一点。)如果我增加到%20或更多来保证这一点,那么左边的填充空间就太多了。(希望最大的值没有前导空格)我也会收回橱柜解决方案!请发布不起作用的代码。