Python中的十进制对齐格式 [英] Decimal alignment formatting in Python

查看:228
本文介绍了Python中的十进制对齐格式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个应该很简单。

这里是我的数组(而是一个产生代表性测试数组的方法): b
$ b

 >>> ri = numpy.random.randint 
>>> (ri(0,9,x).astype('S'))
>>> (1,10,(10,2))]]
>>>的数组a = array([float(ri2(x)+'。'+ ri2(y) a
array([7.99914000e + 01,2.08000000e + 01,3.9000000e + 02,
4.66100000e + 03,5.00000000e + 00,1.72575100e + 03,
3.91500000e + 02 ,1.90610000e + 04,1.6247000e + 04,
3.53920000e + 02])

我想要一个'\\\
'.join(list_o_strings)会打印的字符串列表:

  79.9914 
20.8
394.0
4661.0
5.0
1725.751
391.5
19061.0
11624.7
353.92

我想将空格填充到左边的右边(但是没有必要)。 b
$ b

我想在小数点后面有一个零,如果那是小数点后面的数字。

我不想要科学记数法。 / p>

..我不想丢失任何有效数字。 (在353.98000000000002这2个不显着)

是的,很高兴想要..



Python 2.5' s %g,%fx.x 等等或者让我迷惑,或者不能做到。
我还没有试过 import decimal 。我看不到 NumPy 可以做到这一点(尽管 array .__ str __ 数组.__ repr __ 是十进制对齐的(但有时会返回科学的)。



(e)将数组中的每个元素分割('。'),然后将pad()和

  • 分离到str(a)并解析NumPy的括号重新构造

  • 到a.astype('S'+ str(i)),其中i是max(len(str(a))),然后填充

    似乎应该有一些现成的解决方案在那里...(但不是必需的)
    $ b $当 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'\\\
    '.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 a]

    print'\\\
    '。 join(thelist)

    是快速和简洁的,但是打破了现成的 - 它是一个通用格式的模块化组合(几乎可以做你想做的事情,但是想要隐藏尾随零)和一个RE去除不希望出现的尾随零。实际上,我认为它完全符合你的要求,但是你所说的条件是,我相信这是过度的限制。

    编辑:original问题被编辑为指定更有效的数字,不需要超出最大数字所需的额外的前导空间,并提供一个新的例子(我以前的建议,上面,不符合所需的输出)。删除一堆字符串中常见的主要空格的工作最好使用 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(
    '\\\
    '.join (a)中x的ut0.sub(r'\1',%20f%x))。splitlines()

    print'\\\
    '.join(thelist)

    发出:

      550.056103 
    6773.83566
    601001.513
    355425142.0
    707254.875
    883.174744
    82.232051
    425076609.0
    62866263.5
    156.503068


    This should be easy.

    Here's my array (rather, a method of generating representative test arrays):

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

    I want a list of strings where '\n'.join(list_o_strings) would print:

       79.9914
       20.8
      394.0
     4661.0
        5.0
     1725.751
      391.5
    19061.0
    11624.7
      353.92
    

    I want to space pad to the left and the right (but no more than necessary).

    I want a zero after the decimal if that is all that is after the decimal.

    I do not want scientific notation.

    ..and I do not want to lose any significant digits. (in 353.98000000000002 the 2 is not significant)

    Yeah, it's nice to want..

    Python 2.5's %g, %fx.x, etc. are either befuddling me, or can't do it. I have not tried import decimal yet. I can't see that NumPy does it either (although, the array.__str__ and array.__repr__ are decimal aligned (but sometimes return scientific).

    Oh, and speed counts. I'm dealing with big arrays here.

    My current solution approaches are:

    1. to str(a) and parse off NumPy's brackets
    2. to str(e) each element in the array and split('.') then pad and reconstruct
    3. to a.astype('S'+str(i)) where i is the max(len(str(a))), then pad

    It seems like there should be some off-the-shelf solution out there... (but not required)

    Top suggestion fails with when dtype is 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
    

    解决方案

    Sorry, but after thorough investigation I can't find any way to perform the task you require without a minimum of post-processing (to strip off the trailing zeros you don't want to see); something like:

    import re
    ut0 = re.compile(r'(\d)0+$')
    
    thelist = [ut0.sub(r'\1', "%12f" % x) for x in a]
    
    print '\n'.join(thelist)
    

    is speedy and concise, but breaks your constraint of being "off-the-shelf" -- it is, instead, a modular combination of general formatting (which almost does what you want but leaves trailing zero you want to hide) and a RE to remove undesired trailing zeros. Practically, I think it does exactly what you require, but your conditions as stated are, I believe, over-constrained.

    Edit: original question was edited to specify more significant digits, require no extra leading space beyond what's required for the largest number, and provide a new example (where my previous suggestion, above, doesn't match the desired output). The work of removing leading whitespace that's common to a bunch of strings is best performed with textwrap.dedent -- but that works on a single string (with newlines) while the required output is a list of strings. No problem, we'll just put the lines together, dedent them, and split them up again:

    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)
    

    emits:

          550.056103
         6773.83566
       601001.513
    355425142.0
       707254.875
          883.174744
           82.232051
    425076609.0
     62866263.5
          156.503068
    

    这篇关于Python中的十进制对齐格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆