2011-10-04 43 views
3

對準我有一些Python代碼看起來是這樣的:自動化的「表格」 Python代碼

rates = {3: [((17500, 99999), Decimal('23425.00'), Decimal('7234.24'))], 
     4: [(( 0, 3510), Decimal('4563.00'), Decimal('5234.00')), 
      ((3510, 17500), Decimal('34578.00'), Decimal('3464.50')), 
      ((17500, 99999), Decimal('18268.00'), Decimal('5734.66'))], 
     5: [((17500, 99999), Decimal('83564.00'), Decimal('3475.60'))]} 

注意,十進制值圍繞小數點對齊的,而整數是右對齊。

是否有一些軟件能夠以自動化的方式執行這種複雜對齊?我會對任何接近的東西感興趣,即使它不能完全符合上述內容。

+0

['pprint.pprint'](http://docs.python.org/library/pprint.html#pprint.pprint)會將'dict'分成像這樣的行,但它不會執行任何操作的數字對齊(這就是爲什麼這是一個評論,而不是答案)。我想你必須寫一些自定義的東西來做到這一點。 – agf

+2

IMO,這種東西從來沒有屬於Python代碼(它是表格數據,而不是表格代碼)。所以即使你「漂亮」,它仍然是醜陋的。從文件加載它。 – wim

+1

通常我會同意「不屬於python代碼」的情緒。問題是數據的結構完全是臨時的,並且與使用數據的代碼高度耦合;因爲我只是在實施其他人制定的規則(實際上有很多其他人),所以我無法對這種特殊性做任何事情。因此,任何外部格式都必須在功能方面接近實際的Python代碼,並且幾乎不可能理解數據而不參考使用它的代碼。 – mithrandi

回答

5

注:我不考慮以下特別理智)

因爲如果你只是打出來的大部分(大多數編輯會幫助您調整您的字典和列表項)原密碼,你應該得到像這樣的東西:

rates = {3: [((17500, 199999), Decimal('23425.00'), Decimal('7234.245'))], 
     4: [((0, 3510), Decimal('4563.00'), Decimal('5234.00')), 
      ((3510, 17500), Decimal('34578.00'), Decimal('464.50')), 
      ((17500, 99999), Decimal('18268.00'), Decimal('5734.66'))], 
     15: [((17500, 99999), Decimal('83564.00'), Decimal('3475.60'))]} 

(我已經做了一些價值更長,有些更短添加更多的怪癖。)

隨着Tabular插件Vim的,在上面的代碼執行,從而以下命令(你可能想在視覺上阻止它)將在你原來的問題相匹配的方式格式化上面的代碼:

:Tab /^[^[(]*\zs[[(]/l0 
:Tab /^[^(]*\zs(/l0 
:Tab /(\zs\d\+\s*,/l0r1 
:Tab /,\s*\zs\d\+)/l1r0 
:Tab /['"]\d*\ze\.\d*['"]/l0r0 

的操作是:

  1. 對準第一[ S和(秒。
  2. 對齊第一個( s,這將修復第一個操作中的錯位。
  3. 右對齊(17500,類似於,的值。
  4. 右對齊類似於,, 99999)類似的值。
  5. .上對齊類似'4563.00'的值。

你能在普通和可視模式中使用的映射:

noremap <leader>ff :Tab /^[^[(]*\zs[[(]/l0<CR> 
        \:Tab /^[^(]*\zs(/l0<CR> 
        \:Tab /(\zs\d\+\s*,/l0r1<CR> 
        \:Tab /,\s*\zs\d\+)/l1r0<CR> 
        \:Tab /['"]\d*\ze\.\d*['"]/l0r0<CR> 

最終結果:

rates = {3: [((17500, 199999), Decimal('23425.00'), Decimal('7234.245'))], 
     4: [(( 0, 3510), Decimal('4563.00'), Decimal('5234.00')), 
       ((3510, 17500), Decimal('34578.00'), Decimal('464.50')), 
       ((17500, 99999), Decimal('18268.00'), Decimal('5734.66'))], 
     15: [((17500, 99999), Decimal('83564.00'), Decimal('3475.60'))]} 

顯然,這些操作的有效性取決於結構和原始格式代碼,但希望這可以激勵你。

2

儘管標準庫pprint模塊會添加空格來使字典和列表至少在屏幕上看起來是合理的,但我知道沒有什麼會例如考慮字符串常量中的句點是重要的並且將足夠的空格添加到對齊它們!除非我有很大的錯誤,否則你可能會一直用Python手動進行這種對齊。

如果您將這些值存儲在純文本的單獨表格文件中,那麼當然,您可能會發現幾個願意幫助您校準小數點的編輯器。

+0

這真的是一個答案嗎? – agf

+1

他問「有沒有一些軟件」,我回答「不」。其中@agf確實是一個答案。 –

+1

我從一位有知識的知識豐富的人那裏找到了這個答案。它給我帶來的信息是,我的小經驗沒有 – eyquem

0

編寫一些代碼來漂亮地打印你認爲合適的任何對齊代碼是相當簡單的;但你必須告訴它要尋找什麼。

當你寫出來的手,你做了很多的風格決定不假思索的不多,但如果你想有一個程序做相同的格式,你必須做出這些決策風格明確。例如,你決定垂直對齊的括號,同時對齊含9個元素的列表,如果它實際上是3組,每組3,而完全無視等級,每個嵌套。

這樣的路線佈局真的只讓與您提供,而不是一般意義上的列表感,讓你不會找到別人做你喜歡做的pre-fab代碼。但顯然這並不意味着你不能自己做。

+0

這可能是某個問題的答案,但不是他所問的問題。他正在尋求一個能夠做到這一點的軟件包。 – agf

+0

我只是想指出整個代碼片段中的嵌套層次完全相同:每個字典值是一個3元組列表;每個3元組由一對整數,一個十進制值和另一個十進制值組成。唯一的區別是3和5的列表只有一個元素,而4的列表有三個元素。我不完全責怪任何人沒有看到蝙蝠,但;) – mithrandi

+0

@agf:重讀最後一段。 – tylerl

2

我遇到了同樣的問題。管理層希望從某種表格格式的數據中打印漂亮的報告。

我不想只是做了一堆用「神奇」的空間來修復對齊打印報表的,所以我想出了這條巨蟒功能:

def column(filename, data, indent=0): 
    """This function takes a list of lists and produces columized output""" 
    # get the width of the columns 
    width = [] 
    for mylist in data: 
     for count, d in enumerate(mylist): 
      if count > (len(width)-1): 
       width.append(len(str(d))) 
      elif len(str(d)) > width[count]: 
       width[count] = len(str(d)) 
    # print the data 
    for mylist in data: 
     line = '{0:<{indent}}'.format('', indent=indent)  
     for count, d in enumerate(mylist): 
      try: 
       line = '%s%s' % (line, '{0:{w},} '.format(d, w=width[count])) 
      except ValueError, e: 
       line = '%s%s' % (line, '{0:{w}} '.format(d, w=width[count])) 
     filename.write(line) 
     filename.write('\n') 

這不是完美的,你你需要調整它來產生你想要的輸出。最具體地說,它目前預計會有一個列表,因爲我想按照特定的順序傳遞,並且字典沒有排序。

2

這是一個代碼,可以做你想做的,AFAIU。

這很大程度上是人造的,因爲它只適用於精確詞典的形狀。
但是,我確定這是一個可以改進的基礎,以考慮其他規範,例如每個元組中的幾個Decimal實例。

from decimal import Decimal 


rates = {3: [(( 500, 999), Decimal('23425.008'), Decimal(' 4.24245'))], 
     281: [(( 0, 10), Decimal('4563.00'), Decimal(' 34.00' )), 
       (( 3510, 500), Decimal(' 578' ), Decimal(' 464.503' )), 
       ((174500, 19), Decimal(' 68.2' ), Decimal('5734'  ))], 
     54: [((93500, 99999), Decimal(' 1564.44'), Decimal(' 75.60' ))]} 



def complex_display(di): 
    K,I1,I2,D1B,D1P,D2B,D2P = [],[],[],[],[],[],[] 

    for key,val in di.iteritems(): 
     K.append(len(str(key))) 
     for (i,j),d1,d2 in val : 
      I1.append(len(str(i))) 
      I2.append(len(str(j))) 
      d1b,d1p = str(d1).split('.') if '.' in str(d1) else (str(d1),'.') 
      d2b,d2p = str(d2).split('.') if '.' in str(d2) else (str(d2),'.') 
      D1B.append(len(d1b)) 
      D1P.append(len(d1p)) 
      D2B.append(len(d2b)) 
      D2P.append(len(d2p)) 

    k = '%%%dd: [' % max(K) 
    fv = "%%s((%%%ds, %%%ds), Decimal('%%%ds.%%-%ds'), Decimal('%%%ds.%%-%ds'))%%s" % (max(I1),max(I2),max(D1B),max(D1P),max(D2B),max(D2P)) 

    def produce(di): 
     for key,val in sorted(di.iteritems()): 
      for n,((i,j),d1,d2) in enumerate(val) : 
       d1b,d1p = str(d1).split('.') if '.' in str(d1) else (str(d1)[0:-2],"") 
       d2b,d2p = str(d2).split('.') if '.' in str(d2) else (str(d2)[0:-2],"") 
       yield fv % ('  ' if n else k % key,i,j,d1b,d1p,d2b,d2p,']' if n+1==len(val) else '') 

    return '\n'.join(produce(di)) 

結果

3: [(( 500, 999), Decimal('23425.008'), Decimal(' 4.24245'))] 
54: [((93500, 99999), Decimal(' 1564.44 '), Decimal(' 75.60 '))] 
281: [(( 0, 10), Decimal(' 4563.00 '), Decimal(' 34.00 ')) 
     (( 3510, 500), Decimal(' 5. '), Decimal(' 464.503 ')) 
     ((174500, 19), Decimal(' 68.2 '), Decimal(' 57.  '))] 

有沒有兩個字符「{」和「}」,這是一個很大的更多的複雜性增加他們微弱的結果。我讓你完成代碼來添加它們,如果你想

結果是按照鍵排序。

+0

請注意,這裏的語法是不適合的Python 2.5,但它工作在2.6和更高版本: 'decimal.InvalidOperation:無效的字面十進制:「1564.44」' 我認爲這可以只通過移動固定的'在模板中。 – mithrandi

+0

爲什麼你會說Python 2.5? Python不是那些癡迷復古兼容性的編程語言之一,所以我認爲pythoneers必須發展 – eyquem

+1

Debian 5.0(「lenny」)作爲默認版本與Python 2.5一起提供;雖然我們後來遷移到6.0(「squeeze」),它的默認版本是Python 2.6,但我懷疑仍然有人在運行2.5,所以我想我會提及它,因爲它在我的記憶中是新鮮的。 – mithrandi