अजगर में अच्छा कॉलम आउटपुट बनाएँ


113

मैं कमांड लाइन व्यवस्थापक टूल के साथ उपयोग करने के लिए अजगर में एक अच्छी कॉलम सूची बनाने की कोशिश कर रहा हूं जो मैं बनाता हूं।

मूल रूप से, मुझे एक सूची चाहिए:

[['a', 'b', 'c'], ['aaaaaaaaaa', 'b', 'c'], ['a', 'bbbbbbbbbb', 'c']]

इसमें बदलने के लिए:

a            b            c
aaaaaaaaaa   b            c
a            bbbbbbbbbb   c

सादे टैब का उपयोग करने से यहाँ चाल नहीं चलेगी क्योंकि मैं प्रत्येक पंक्ति में सबसे लंबे समय तक डेटा नहीं जानता।

यह लिनक्स में 'कॉलम -t' के समान व्यवहार है।

$ echo -e "a b c\naaaaaaaaaa b c\na bbbbbbbbbb c"
a b c
aaaaaaaaaa b c
a bbbbbbbbbb c

$ echo -e "a b c\naaaaaaaaaa b c\na bbbbbbbbbb c" | column -t
a           b           c
aaaaaaaaaa  b           c
a           bbbbbbbbbb  c

मैंने ऐसा करने के लिए विभिन्न अजगर पुस्तकालयों के लिए चारों ओर देखा है, लेकिन कुछ भी उपयोगी नहीं मिल सकता है।


4
सूचनाओं की छोटी ~ 10 पंक्तियों को प्रदर्शित करने के लिए ncurses का उपयोग करना थोड़ा ओवरकिल है। लेकिन हम अन्य सामानों के लिए ncurses का उपयोग कर रहे हैं।
xeor

जवाबों:


121
data = [['a', 'b', 'c'], ['aaaaaaaaaa', 'b', 'c'], ['a', 'bbbbbbbbbb', 'c']]

col_width = max(len(word) for row in data for word in row) + 2  # padding
for row in data:
    print "".join(word.ljust(col_width) for word in row)

a            b            c            
aaaaaaaaaa   b            c            
a            bbbbbbbbbb   c   

कॉलम चौड़ाई निर्धारित करने के लिए यह सबसे लंबी डेटा प्रविष्टि की गणना करता है, फिर .ljust()प्रत्येक कॉलम को प्रिंट करते समय आवश्यक पैडिंग जोड़ने के लिए उपयोग करें।


1
यह नाम longestभ्रामक है क्योंकि यह सबसे लंबा तत्व नहीं है, लेकिन अधिकतम_प्रवाह है। BTW सबसे लंबे समय तक कुछ के साथ लिया जा सकता है max((w for sub in data for w in sub), key=len):। [पीएस मैं नीचे की ओर नहीं था]
रिक पोगी

1
max((w for ...), key=len)आपको सबसे लंबी प्रविष्टि देता है और आपको फिर से एक रन करने की आवश्यकता होगी len। यह तय नहीं किया जा सका कि मैं कौन से स्पष्ट था इसलिए मैं पहले से ही अटका रहा। भ्रामक var नाम पर अच्छा बिंदु। बदला हुआ।
शॉन चिन

1
हां, एक या दूसरे के साथ कोई बड़ा अंतर नहीं है, सिर्फ स्वाद की बात है। इसके अलावा, जैसा कि आपने देखा, वह रेखा थोड़ी (बहुत) भ्रमित है। इसे सीधे करना बेहतर होगा: max(len(x) for sub in data for x in sub)यह भी अनावश्यक सूचियों का निर्माण नहीं करता है।
रिक पोगी

1
धन्यवाद! यह ठीक वैसा ही है जैसा मुझे चाहिए। हालाँकि, मुझे इसे अजगर 2.4 के साथ काम करने के लिए प्राप्त करना था, इसलिए मैंने chain.from_iterable को दूर कर दिया, और सुझाए गए उप में x के लिए अधिकतम (len (x) के साथ डेटा के लिए col_width को प्रतिस्थापित कर दिया + 2 का सुझाव दिया। आशा है कि आप अपना कोड बदल सकते हैं ताकि यह स्पष्ट हो सके कि कोई और इसे 2.4 के साथ चलाना चाहता है।
xeor

1
यह सभी स्तंभों को समान चौड़ाई देगा, जो ऐसा नहीं column -tकरता है।
intuited

145

पायथन 2.6+ के बाद से, आप एक का उपयोग कर सकते हैं स्तंभों को न्यूनतम 20 वर्णों में सेट करने और टेक्स्ट को दाईं ओर संरेखित करने के लिए निम्न तरीके से प्रारूप स्ट्रिंग का

table_data = [
    ['a', 'b', 'c'],
    ['aaaaaaaaaa', 'b', 'c'], 
    ['a', 'bbbbbbbbbb', 'c']
]
for row in table_data:
    print("{: >20} {: >20} {: >20}".format(*row))

आउटपुट:

               a                    b                    c
      aaaaaaaaaa                    b                    c
               a           bbbbbbbbbb                    c

10
अब तक का सबसे अच्छा समाधान
zlr

यह केवल कभी 9 आइटम दिखाता है जब मैंने इसका उपयोग करने की कोशिश की।
डोरियन डोर

और आप बस {: >20}अधिक फ़ील्ड प्रदर्शित करने के लिए जोड़ते रह सकते हैं
PercussiveRepair

8
ऊपर दिखाए गए प्रारूप विनिर्देशक में कुर्ज्डमेटल से समाधान जोड़ना; {:> 20},> सही संरेखण इंगित करता है। {: <20} का उपयोग करके आपको एक बाएं संरेखित स्तंभ मिलेगा और {: ^ 20} का उपयोग करके आपको एक केंद्रित संरेखित स्तंभ मिलेगा।
डेल मूर

1
मुझे नहीं लगता कि यह सवाल का जवाब देता है - ऐसा लगता है कि ओपी प्रत्येक पंक्ति को अपनी सामग्री को धारण करने की आवश्यकता से अधिक व्यापक नहीं बनाना चाहता है। यह सिर्फ 20 वर्ष की एक निश्चित चौड़ाई सेट
intuited

43

मैं समान आवश्यकताओं के साथ यहाँ आया था, लेकिन @lvc और @ प्रीत के उत्तर अधिक column -tस्तंभों में अलग-अलग चौड़ाई के उत्पादन के साथ अधिक इनलाइन लगते हैं :

>>> rows =  [   ['a',           'b',            'c',    'd']
...         ,   ['aaaaaaaaaa',  'b',            'c',    'd']
...         ,   ['a',           'bbbbbbbbbb',   'c',    'd']
...         ]
...

>>> widths = [max(map(len, col)) for col in zip(*rows)]
>>> for row in rows:
...     print "  ".join((val.ljust(width) for val, width in zip(row, widths)))
...
a           b           c  d
aaaaaaaaaa  b           c  d
a           bbbbbbbbbb  c  d

2
अच्छा लगा। यह सबसे स्पष्ट समाधान है जो वास्तव में मूल "कल्पना" का अनुसरण करता है।
intuited

2
यह वह उपाय है जो मेरे लिए काम करता है। अन्य समाधानों ने स्तंभ उत्पादन का उत्पादन किया लेकिन इसने सटीक स्तंभ चौड़ाई के साथ-साथ पैडिंग पर सबसे अधिक नियंत्रण दिया।
माइकल जे।

1
सुंदर समाधान। किसी भी कॉलम में तार नहीं हैं, बस एक अतिरिक्त नक्शा जोड़ें map(len, map(str, col)):।
ड्रॉक्ल्स

11

यह पार्टी के लिए थोड़ी देर है, और मेरे द्वारा लिखे गए पैकेज के लिए एक बेशर्म प्लग है, लेकिन आप कॉलमीनर पैकेज भी देख सकते हैं ।

यह इनपुट की सूची और हेडर की सूची लेता है और तालिका-स्वरूपित स्ट्रिंग को आउटपुट करता है। यह स्निपेट एक डॉक-एस्क टेबल बनाता है:

from columnar import columnar

headers = ['name', 'id', 'host', 'notes']

data = [
    ['busybox', 'c3c37d5d-38d2-409f-8d02-600fd9d51239', 'linuxnode-1-292735', 'Test server.'],
    ['alpine-python', '6bb77855-0fda-45a9-b553-e19e1a795f1e', 'linuxnode-2-249253', 'The one that runs python.'],
    ['redis', 'afb648ba-ac97-4fb2-8953-9a5b5f39663e', 'linuxnode-3-3416918', 'For queues and stuff.'],
    ['app-server', 'b866cd0f-bf80-40c7-84e3-c40891ec68f9', 'linuxnode-4-295918', 'A popular destination.'],
    ['nginx', '76fea0f0-aa53-4911-b7e4-fae28c2e469b', 'linuxnode-5-292735', 'Traffic Cop'],
]

table = columnar(data, headers, no_borders=True)
print(table)

टेबल-नो-बॉर्डर स्टाइल प्रदर्शित करना

या आप रंगों और सीमाओं के साथ थोड़ा प्रशंसक पा सकते हैं। स्प्रिंग क्लासिक्स प्रदर्शित तालिका

कॉलम-साइज़िंग एल्गोरिदम के बारे में अधिक पढ़ने के लिए और बाकी एपीआई को देखने के लिए आप ऊपर दिए गए लिंक की जाँच कर सकते हैं या कॉलमीनर गिटहब रेपो देखें


यह पैकेज बढ़िया काम करता है, साझा करने के लिए धन्यवाद
wonton

8

आपको इसे 2 पास के साथ करना होगा:

  1. प्रत्येक स्तंभ की अधिकतम चौड़ाई प्राप्त करें।
  2. पहले पास का उपयोग करके str.ljust()और अधिकतम चौड़ाई के हमारे ज्ञान का उपयोग करते हुए स्तंभों को स्वरूपित करनाstr.rjust()

7

कॉलम को इस तरह ट्रांसप्लांट करना ज़िप के लिए एक काम है:

>>> a = [['a', 'b', 'c'], ['aaaaaaaaaa', 'b', 'c'], ['a', 'bbbbbbbbbb', 'c']]
>>> list(zip(*a))
[('a', 'aaaaaaaaaa', 'a'), ('b', 'b', 'bbbbbbbbbb'), ('c', 'c', 'c')]

प्रत्येक स्तंभ की आवश्यक लंबाई जानने के लिए, आप उपयोग कर सकते हैं max:

>>> trans_a = zip(*a)
>>> [max(len(c) for c in b) for b in trans_a]
[10, 10, 1]

जिसे आप उपयुक्त पैडिंग के साथ उपयोग कर सकते हैं print:

>>> col_lenghts = [max(len(c) for c in b) for b in trans_a]
>>> padding = ' ' # You might want more
>>> padding.join(s.ljust(l) for s,l in zip(a[0], col_lenghts))
'a          b          c'

6

जैसे कट्टरपंथी टेबल पाने के लिए

---------------------------------------------------
| First Name | Last Name        | Age | Position  |
---------------------------------------------------
| John       | Smith            | 24  | Software  |
|            |                  |     | Engineer  |
---------------------------------------------------
| Mary       | Brohowski        | 23  | Sales     |
|            |                  |     | Manager   |
---------------------------------------------------
| Aristidis  | Papageorgopoulos | 28  | Senior    |
|            |                  |     | Reseacher |
---------------------------------------------------

आप इस पायथन नुस्खा का उपयोग कर सकते हैं :

'''
From http://code.activestate.com/recipes/267662-table-indentation/
PSF License
'''
import cStringIO,operator

def indent(rows, hasHeader=False, headerChar='-', delim=' | ', justify='left',
           separateRows=False, prefix='', postfix='', wrapfunc=lambda x:x):
    """Indents a table by column.
       - rows: A sequence of sequences of items, one sequence per row.
       - hasHeader: True if the first row consists of the columns' names.
       - headerChar: Character to be used for the row separator line
         (if hasHeader==True or separateRows==True).
       - delim: The column delimiter.
       - justify: Determines how are data justified in their column. 
         Valid values are 'left','right' and 'center'.
       - separateRows: True if rows are to be separated by a line
         of 'headerChar's.
       - prefix: A string prepended to each printed row.
       - postfix: A string appended to each printed row.
       - wrapfunc: A function f(text) for wrapping text; each element in
         the table is first wrapped by this function."""
    # closure for breaking logical rows to physical, using wrapfunc
    def rowWrapper(row):
        newRows = [wrapfunc(item).split('\n') for item in row]
        return [[substr or '' for substr in item] for item in map(None,*newRows)]
    # break each logical row into one or more physical ones
    logicalRows = [rowWrapper(row) for row in rows]
    # columns of physical rows
    columns = map(None,*reduce(operator.add,logicalRows))
    # get the maximum of each column by the string length of its items
    maxWidths = [max([len(str(item)) for item in column]) for column in columns]
    rowSeparator = headerChar * (len(prefix) + len(postfix) + sum(maxWidths) + \
                                 len(delim)*(len(maxWidths)-1))
    # select the appropriate justify method
    justify = {'center':str.center, 'right':str.rjust, 'left':str.ljust}[justify.lower()]
    output=cStringIO.StringIO()
    if separateRows: print >> output, rowSeparator
    for physicalRows in logicalRows:
        for row in physicalRows:
            print >> output, \
                prefix \
                + delim.join([justify(str(item),width) for (item,width) in zip(row,maxWidths)]) \
                + postfix
        if separateRows or hasHeader: print >> output, rowSeparator; hasHeader=False
    return output.getvalue()

# written by Mike Brown
# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/148061
def wrap_onspace(text, width):
    """
    A word-wrap function that preserves existing line breaks
    and most spaces in the text. Expects that existing line
    breaks are posix newlines (\n).
    """
    return reduce(lambda line, word, width=width: '%s%s%s' %
                  (line,
                   ' \n'[(len(line[line.rfind('\n')+1:])
                         + len(word.split('\n',1)[0]
                              ) >= width)],
                   word),
                  text.split(' ')
                 )

import re
def wrap_onspace_strict(text, width):
    """Similar to wrap_onspace, but enforces the width constraint:
       words longer than width are split."""
    wordRegex = re.compile(r'\S{'+str(width)+r',}')
    return wrap_onspace(wordRegex.sub(lambda m: wrap_always(m.group(),width),text),width)

import math
def wrap_always(text, width):
    """A simple word-wrap function that wraps text on exactly width characters.
       It doesn't split the text in words."""
    return '\n'.join([ text[width*i:width*(i+1)] \
                       for i in xrange(int(math.ceil(1.*len(text)/width))) ])

if __name__ == '__main__':
    labels = ('First Name', 'Last Name', 'Age', 'Position')
    data = \
    '''John,Smith,24,Software Engineer
       Mary,Brohowski,23,Sales Manager
       Aristidis,Papageorgopoulos,28,Senior Reseacher'''
    rows = [row.strip().split(',')  for row in data.splitlines()]

    print 'Without wrapping function\n'
    print indent([labels]+rows, hasHeader=True)
    # test indent with different wrapping functions
    width = 10
    for wrapper in (wrap_always,wrap_onspace,wrap_onspace_strict):
        print 'Wrapping function: %s(x,width=%d)\n' % (wrapper.__name__,width)
        print indent([labels]+rows, hasHeader=True, separateRows=True,
                     prefix='| ', postfix=' |',
                     wrapfunc=lambda x: wrapper(x,width))

    # output:
    #
    #Without wrapping function
    #
    #First Name | Last Name        | Age | Position         
    #-------------------------------------------------------
    #John       | Smith            | 24  | Software Engineer
    #Mary       | Brohowski        | 23  | Sales Manager    
    #Aristidis  | Papageorgopoulos | 28  | Senior Reseacher 
    #
    #Wrapping function: wrap_always(x,width=10)
    #
    #----------------------------------------------
    #| First Name | Last Name  | Age | Position   |
    #----------------------------------------------
    #| John       | Smith      | 24  | Software E |
    #|            |            |     | ngineer    |
    #----------------------------------------------
    #| Mary       | Brohowski  | 23  | Sales Mana |
    #|            |            |     | ger        |
    #----------------------------------------------
    #| Aristidis  | Papageorgo | 28  | Senior Res |
    #|            | poulos     |     | eacher     |
    #----------------------------------------------
    #
    #Wrapping function: wrap_onspace(x,width=10)
    #
    #---------------------------------------------------
    #| First Name | Last Name        | Age | Position  |
    #---------------------------------------------------
    #| John       | Smith            | 24  | Software  |
    #|            |                  |     | Engineer  |
    #---------------------------------------------------
    #| Mary       | Brohowski        | 23  | Sales     |
    #|            |                  |     | Manager   |
    #---------------------------------------------------
    #| Aristidis  | Papageorgopoulos | 28  | Senior    |
    #|            |                  |     | Reseacher |
    #---------------------------------------------------
    #
    #Wrapping function: wrap_onspace_strict(x,width=10)
    #
    #---------------------------------------------
    #| First Name | Last Name  | Age | Position  |
    #---------------------------------------------
    #| John       | Smith      | 24  | Software  |
    #|            |            |     | Engineer  |
    #---------------------------------------------
    #| Mary       | Brohowski  | 23  | Sales     |
    #|            |            |     | Manager   |
    #---------------------------------------------
    #| Aristidis  | Papageorgo | 28  | Senior    |
    #|            | poulos     |     | Reseacher |
    #---------------------------------------------

अजगर नुस्खा पेज उस पर कुछ सुधार शामिल हैं।


5

pandas डेटाफ्रेम बनाने के साथ आधारित समाधान:

import pandas as pd
l = [['a', 'b', 'c'], ['aaaaaaaaaa', 'b', 'c'], ['a', 'bbbbbbbbbb', 'c']]
df = pd.DataFrame(l)

print(df)
            0           1  2
0           a           b  c
1  aaaaaaaaaa           b  c
2           a  bbbbbbbbbb  c

उत्पादन करने के लिए इंडेक्स और हेडर मानों को हटाने के लिए जो आप चाहते हैं कि आप to_stringविधि का उपयोग कर सकते हैं :

result = df.to_string(index=False, header=False)

print(result)
          a           b  c
 aaaaaaaaaa           b  c
          a  bbbbbbbbbb  c

1

Scolp एक नई लाइब्रेरी है जो आपको ऑटो-समायोजन कॉलम की चौड़ाई के दौरान आसानी से स्ट्रीमिंग स्तंभ के डेटा को आसानी से प्रिंट करने देती है।

(अस्वीकरण: मैं लेखक हूं)


1

यह अन्य उत्तरों में प्रयुक्त अधिकतम-मीट्रिक के आधार पर स्वतंत्र, सर्वश्रेष्ठ-फिट कॉलम की चौड़ाई निर्धारित करता है।

data = [['a', 'b', 'c'], ['aaaaaaaaaa', 'b', 'c'], ['a', 'bbbbbbbbbb', 'c']]
padding = 2
col_widths = [max(len(w) for w in [r[cn] for r in data]) + padding for cn in range(len(data[0]))]
format_string = "{{:{}}}{{:{}}}{{:{}}}".format(*col_widths)
for row in data:
    print(format_string.format(*row))

यह बेहतर जवाब है, हालांकि कोड थोड़ा बदबूदार है।
सैम मॉर्गन

1

आलसी लोगों के लिए

जो कि पायथन 3. * और पंडों / जियोपैन्डस का उपयोग कर रहे हैं ; सार्वभौमिक सरल इन-क्लास दृष्टिकोण ('सामान्य' स्क्रिप्ट के लिए केवल स्वयं को हटा दें ):

समारोह colorize:

    def colorize(self,s,color):
        s = color+str(s)+"\033[0m"
        return s

हैडर:

print('{0:<23} {1:>24} {2:>26} {3:>26} {4:>11} {5:>11}'.format('Road name','Classification','Function','Form of road','Length','Distance') )

और फिर पंडों / जियोपैन्डस डेटाफ्रेम के डेटा:

            for index, row in clipped.iterrows():
                rdName      = self.colorize(row['name1'],"\033[32m")
                rdClass     = self.colorize(row['roadClassification'],"\033[93m")
                rdFunction  = self.colorize(row['roadFunction'],"\033[33m")
                rdForm      = self.colorize(row['formOfWay'],"\033[94m")
                rdLength    = self.colorize(row['length'],"\033[97m")
                rdDistance  = self.colorize(row['distance'],"\033[96m")
                print('{0:<30} {1:>35} {2:>35} {3:>35} {4:>20} {5:>20}'.format(rdName,rdClass,rdFunction,rdForm,rdLength,rdDistance) )

का अर्थ {0:<30} {1:>35} {2:>35} {3:>35} {4:>20} {5:>20}:

0, 1, 2, 3, 4, 5 -> कॉलम, इस मामले में कुल 6 हैं

30, 35, 20-> कॉलम की चौड़ाई (ध्यान दें कि आपको लंबाई जोड़ना होगा \033[96m- यह पायथन के लिए एक स्ट्रिंग है), बस प्रयोग :)

>, <-> सही: बाएं ( =शून्य के साथ भरने के लिए भी है)

यदि आप उदाहरण के लिए अधिकतम मान को अलग करना चाहते हैं, तो आपको विशेष पंडास शैली फ़ंक्शन पर स्विच करना होगा, लेकिन मान लें कि यह टर्मिनल विंडो पर डेटा प्रस्तुत करने के लिए पर्याप्त है।

परिणाम:

यहां छवि विवरण दर्ज करें


1

पिछले उत्तर पर थोड़ा बदलाव (मेरे पास इस पर टिप्पणी करने के लिए पर्याप्त प्रतिनिधि नहीं है)। प्रारूप लाइब्रेरी आपको किसी तत्व की चौड़ाई और संरेखण को निर्दिष्ट करने देता है, लेकिन ऐसा नहीं है जहां यह शुरू होता है, अर्थात, आप कह सकते हैं "20 कॉलम चौड़ा हो" लेकिन "कॉलम 20 में शुरू नहीं"। इस मुद्दे की ओर जाता है:

table_data = [
    ['a', 'b', 'c'],
    ['aaaaaaaaaa', 'b', 'c'], 
    ['a', 'bbbbbbbbbb', 'c']
]

print("first row: {: >20} {: >20} {: >20}".format(*table_data[0]))
print("second row: {: >20} {: >20} {: >20}".format(*table_data[1]))
print("third row: {: >20} {: >20} {: >20}".format(*table_data[2]))

उत्पादन

first row:                    a                    b                    c
second row:           aaaaaaaaaa                    b                    c
third row:                    a           bbbbbbbbbb                    c

पाठ्यक्रम का उत्तर शाब्दिक तार को प्रारूपित करना है, जो प्रारूप के साथ थोड़ा अजीब रूप से जोड़ता है:

table_data = [
    ['a', 'b', 'c'],
    ['aaaaaaaaaa', 'b', 'c'], 
    ['a', 'bbbbbbbbbb', 'c']
]

print(f"{'first row:': <20} {table_data[0][0]: >20} {table_data[0][1]: >20} {table_data[0][2]: >20}")
print("{: <20} {: >20} {: >20} {: >20}".format(*['second row:', *table_data[1]]))
print("{: <20} {: >20} {: >20} {: >20}".format(*['third row:', *table_data[1]]))

उत्पादन

first row:                              a                    b                    c
second row:                    aaaaaaaaaa                    b                    c
third row:                     aaaaaaaaaa                    b                    c

0

मुझे यह उत्तर सुपर-सहायक और सुरुचिपूर्ण मिला, मूल रूप से यहाँ से :

matrix = [["A", "B"], ["C", "D"]]

print('\n'.join(['\t'.join([str(cell) for cell in row]) for row in matrix]))

उत्पादन

A   B
C   D

0

यहाँ शॉन चिन के उत्तर की भिन्नता है। चौड़ाई प्रति कॉलम तय की गई है, सभी कॉलमों पर नहीं। पहली पंक्ति के नीचे और स्तंभों के बीच एक सीमा भी है। ( अनुबंध को लागू करने के लिए icontract लाइब्रेरी का उपयोग किया जाता है।)

@icontract.pre(
    lambda table: not table or all(len(row) == len(table[0]) for row in table))
@icontract.post(lambda table, result: result == "" if not table else True)
@icontract.post(lambda result: not result.endswith("\n"))
def format_table(table: List[List[str]]) -> str:
    """
    Format the table as equal-spaced columns.

    :param table: rows of cells
    :return: table as string
    """
    cols = len(table[0])

    col_widths = [max(len(row[i]) for row in table) for i in range(cols)]

    lines = []  # type: List[str]
    for i, row in enumerate(table):
        parts = []  # type: List[str]

        for cell, width in zip(row, col_widths):
            parts.append(cell.ljust(width))

        line = " | ".join(parts)
        lines.append(line)

        if i == 0:
            border = []  # type: List[str]

            for width in col_widths:
                border.append("-" * width)

            lines.append("-+-".join(border))

    result = "\n".join(lines)

    return result

यहाँ एक उदाहरण है:

>>> table = [['column 0', 'another column 1'], ['00', '01'], ['10', '11']]
>>> result = packagery._format_table(table=table)
>>> print(result)
column 0 | another column 1
---------+-----------------
00       | 01              
10       | 11              

0

अपडेट किया गया @ फ्रेंक डर्नोनकोर्ट फैंसी नुस्खा पायथन 3 और पीईपी 8 का अनुपालन करता है

import io
import math
import operator
import re
import functools

from itertools import zip_longest


def indent(
    rows,
    has_header=False,
    header_char="-",
    delim=" | ",
    justify="left",
    separate_rows=False,
    prefix="",
    postfix="",
    wrapfunc=lambda x: x,
):
    """Indents a table by column.
       - rows: A sequence of sequences of items, one sequence per row.
       - hasHeader: True if the first row consists of the columns' names.
       - headerChar: Character to be used for the row separator line
         (if hasHeader==True or separateRows==True).
       - delim: The column delimiter.
       - justify: Determines how are data justified in their column.
         Valid values are 'left','right' and 'center'.
       - separateRows: True if rows are to be separated by a line
         of 'headerChar's.
       - prefix: A string prepended to each printed row.
       - postfix: A string appended to each printed row.
       - wrapfunc: A function f(text) for wrapping text; each element in
         the table is first wrapped by this function."""

    # closure for breaking logical rows to physical, using wrapfunc
    def row_wrapper(row):
        new_rows = [wrapfunc(item).split("\n") for item in row]
        return [[substr or "" for substr in item] for item in zip_longest(*new_rows)]

    # break each logical row into one or more physical ones
    logical_rows = [row_wrapper(row) for row in rows]
    # columns of physical rows
    columns = zip_longest(*functools.reduce(operator.add, logical_rows))
    # get the maximum of each column by the string length of its items
    max_widths = [max([len(str(item)) for item in column]) for column in columns]
    row_separator = header_char * (
        len(prefix) + len(postfix) + sum(max_widths) + len(delim) * (len(max_widths) - 1)
    )
    # select the appropriate justify method
    justify = {"center": str.center, "right": str.rjust, "left": str.ljust}[
        justify.lower()
    ]
    output = io.StringIO()
    if separate_rows:
        print(output, row_separator)
    for physicalRows in logical_rows:
        for row in physicalRows:
            print( output, prefix + delim.join(
                [justify(str(item), width) for (item, width) in zip(row, max_widths)]
            ) + postfix)
        if separate_rows or has_header:
            print(output, row_separator)
            has_header = False
    return output.getvalue()


# written by Mike Brown
# http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/148061
def wrap_onspace(text, width):
    """
    A word-wrap function that preserves existing line breaks
    and most spaces in the text. Expects that existing line
    breaks are posix newlines (\n).
    """
    return functools.reduce(
        lambda line, word, i_width=width: "%s%s%s"
        % (
            line,
            " \n"[
                (
                    len(line[line.rfind("\n") + 1 :]) + len(word.split("\n", 1)[0])
                    >= i_width
                )
            ],
            word,
        ),
        text.split(" "),
    )


def wrap_onspace_strict(text, i_width):
    """Similar to wrap_onspace, but enforces the width constraint:
       words longer than width are split."""
    word_regex = re.compile(r"\S{" + str(i_width) + r",}")
    return wrap_onspace(
        word_regex.sub(lambda m: wrap_always(m.group(), i_width), text), i_width
    )


def wrap_always(text, width):
    """A simple word-wrap function that wraps text on exactly width characters.
       It doesn't split the text in words."""
    return "\n".join(
        [
            text[width * i : width * (i + 1)]
            for i in range(int(math.ceil(1.0 * len(text) / width)))
        ]
    )


if __name__ == "__main__":
    labels = ("First Name", "Last Name", "Age", "Position")
    data = """John,Smith,24,Software Engineer
           Mary,Brohowski,23,Sales Manager
           Aristidis,Papageorgopoulos,28,Senior Reseacher"""
    rows = [row.strip().split(",") for row in data.splitlines()]

    print("Without wrapping function\n")
    print(indent([labels] + rows, has_header=True))

    # test indent with different wrapping functions
    width = 10
    for wrapper in (wrap_always, wrap_onspace, wrap_onspace_strict):
        print("Wrapping function: %s(x,width=%d)\n" % (wrapper.__name__, width))

        print(
            indent(
                [labels] + rows,
                has_header=True,
                separate_rows=True,
                prefix="| ",
                postfix=" |",
                wrapfunc=lambda x: wrapper(x, width),
            )
        )

    # output:
    #
    # Without wrapping function
    #
    # First Name | Last Name        | Age | Position
    # -------------------------------------------------------
    # John       | Smith            | 24  | Software Engineer
    # Mary       | Brohowski        | 23  | Sales Manager
    # Aristidis  | Papageorgopoulos | 28  | Senior Reseacher
    #
    # Wrapping function: wrap_always(x,width=10)
    #
    # ----------------------------------------------
    # | First Name | Last Name  | Age | Position   |
    # ----------------------------------------------
    # | John       | Smith      | 24  | Software E |
    # |            |            |     | ngineer    |
    # ----------------------------------------------
    # | Mary       | Brohowski  | 23  | Sales Mana |
    # |            |            |     | ger        |
    # ----------------------------------------------
    # | Aristidis  | Papageorgo | 28  | Senior Res |
    # |            | poulos     |     | eacher     |
    # ----------------------------------------------
    #
    # Wrapping function: wrap_onspace(x,width=10)
    #
    # ---------------------------------------------------
    # | First Name | Last Name        | Age | Position  |
    # ---------------------------------------------------
    # | John       | Smith            | 24  | Software  |
    # |            |                  |     | Engineer  |
    # ---------------------------------------------------
    # | Mary       | Brohowski        | 23  | Sales     |
    # |            |                  |     | Manager   |
    # ---------------------------------------------------
    # | Aristidis  | Papageorgopoulos | 28  | Senior    |
    # |            |                  |     | Reseacher |
    # ---------------------------------------------------
    #
    # Wrapping function: wrap_onspace_strict(x,width=10)
    #
    # ---------------------------------------------
    # | First Name | Last Name  | Age | Position  |
    # ---------------------------------------------
    # | John       | Smith      | 24  | Software  |
    # |            |            |     | Engineer  |
    # ---------------------------------------------
    # | Mary       | Brohowski  | 23  | Sales     |
    # |            |            |     | Manager   |
    # ---------------------------------------------
    # | Aristidis  | Papageorgo | 28  | Senior    |
    # |            | poulos     |     | Reseacher |
    # ---------------------------------------------

-1

मुझे लगता है कि यह सवाल पुराना है, लेकिन मैं एंटक के जवाब को नहीं समझ पाया और लाइब्रेरी का उपयोग नहीं करना चाहता था, इसलिए मैंने अपना समाधान निकाला।

समाधान मानता है कि रिकॉर्ड एक 2 डी सरणी है, रिकॉर्ड सभी एक ही लंबाई के हैं, और यह कि फ़ील्ड सभी तार हैं।

def stringifyRecords(records):
    column_widths = [0] * len(records[0])
    for record in records:
        for i, field in enumerate(record):
            width = len(field)
            if width > column_widths[i]: column_widths[i] = width

    s = ""
    for record in records:
        for column_width, field in zip(column_widths, record):
            s += field.ljust(column_width+1)
        s += "\n"

    return s
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.