2009-06-22 84 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實際上可以做你想做的事,因爲如果它太長,你通常會希望它處於指數模式。