পাইথনে সুন্দর কলাম আউটপুট তৈরি করুন


113

আমি তৈরি কমান্ডলাইন অ্যাডমিন সরঞ্জামগুলির সাহায্যে পাইথনে একটি দুর্দান্ত কলাম তালিকা তৈরি করার চেষ্টা করছি।

মূলতঃ, আমি এর মতো একটি তালিকা চাই:

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

পরিবর্তন করতে:

a            b            c
aaaaaaaaaa   b            c
a            bbbbbbbbbb   c

সরল ট্যাব ব্যবহার করে এখানে কৌশলটি করা হবে না কারণ আমি প্রতিটি সারিতে দীর্ঘতম ডেটা জানি না।

এটি লিনাক্সের 'কলাম-ট' এর মতো একই আচরণ ..

$ 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 ডলার লাইন তথ্য প্রদর্শন করার জন্য এনকার্স ব্যবহার করা একটু ওভারকিল .. তবে আমরা অন্যান্য স্টাফের জন্য এনক্রস ব্যবহার করছি।
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আবার রান করতে হবে। কোনটি পরিষ্কার ছিল তা ঠিক করতে পারিনি তাই আমি প্রথমটির সাথে আটকে গেলাম। বিভ্রান্তকারী বর্ণের ভাল পয়েন্ট। পরিবর্তন হয়েছে।
শন চিন

1
হ্যাঁ, একটি বা অন্যটির সাথে কোনও বড় পার্থক্য নেই, আমি যা বলতে চাই তার স্বাদের বিষয়। এগুলি ছাড়াও, আপনি যেমন লক্ষ্য করেছেন, সেই লাইনটি কিছুটা (খুব) বিভ্রান্ত। এটি সরাসরি করা ভাল হবে:, এটি max(len(x) for sub in data for x in sub)অপ্রয়োজনীয় তালিকা তৈরি করে না।
রিক পোগি

1
ধন্যবাদ! এটি আমার প্রয়োজন ঠিক তাই। যাইহোক, পাইথন ২.৪ এর সাথে কাজ করার জন্যও আমাকে এটি পেতে হয়েছিল, তাই আমি চ্যানেল.ফর্ম_আটারেবলকে টোকা দিয়েছি, এবং পরামর্শ অনুসারে x_ উপাত্তের জন্য সাব-লেনের জন্য কল_উইথকে সর্বাধিক (লেন (এক্স)) প্রতিস্থাপন করেছি 2 আশা করি অন্য কেউ যদি এটি ২.৪ সহ চালাতে চায় তবে এটি পরিষ্কার করার জন্য আপনি উপরের কোডটি পরিবর্তন করতে পারবেন।
xeor

1
এটি সমস্ত কলামকে একই প্রস্থে তৈরি করবে, যা তা column -tকরে না।
5:54

145

পাইথন ২.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}আরও ক্ষেত্র প্রদর্শন করতে যোগ করতে পারেন
পারকুসিউসিপেইপায়ার

8
উপরের দেখানো ফর্ম্যাট স্পেসিফায়ারে কুর্জেডমেটাল থেকে সমাধানটিতে যোগ করা; {:> 20},>> ডান প্রান্তিককরণ নির্দেশ করে। {: <20 using ব্যবহার করে আপনি একটি বাম প্রান্তিককরণ কলাম পাবেন এবং {: ^ 20 using ব্যবহার করে আপনি একটি কেন্দ্রিক প্রান্তিককরণ কলাম পাবেন get
ডেল মুর

1
আমি মনে করি না যে এটির প্রশ্নের উত্তর — এটি মনে হচ্ছে যে ওপি প্রতিটি সারিকে এর বিষয়বস্তু রাখার জন্য আরও বিস্তৃত করতে চায় না। এই মাত্র 20 একটি নির্দিষ্ট প্রস্থ নির্ধারণ
intuited

43

আমি এখানে একই প্রয়োজনীয়তা নিয়ে এসেছি কিন্তু @ এলভিসি এবং @ প্রীতের উত্তরগুলি 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
খুশী হলাম। এটিই স্পষ্ট সমাধান যা আসলে আসল "স্পেক" অনুসরণ করে।
5:55

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)

সারণী প্রদর্শন করছে নো-বর্ডার স্টাইল

অথবা আপনি রঙ এবং সীমানা দিয়ে কিছুটা ফ্যানসিয়ার পেতে পারেন। সারণী প্রদর্শন স্প্রিং ক্লাসিক

কলাম-সাইজিং অ্যালগরিদম সম্পর্কে আরও পড়তে এবং বাকি API টি দেখতে আপনি উপরের লিঙ্কটি পরীক্ষা করে দেখতে পারেন বা কলামার গিটহাব রেপো দেখতে পারেন


এই প্যাকেজটি দুর্দান্ত কাজ করে, ভাগ করে নেওয়ার জন্য ধন্যবাদ
18.33

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

স্কলপ একটি নতুন লাইব্রেরি যা কলামের প্রস্থকে স্বয়ংক্রিয়ভাবে সামঞ্জস্য করার সময় আপনাকে সহজেই স্ট্রিমিং কলামার ডেটা প্রিন্ট করতে দেয়।

(অস্বীকৃতি: আমি লেখক)


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 ব্যবহার করছে * * এবং পান্ডস / জিওপ্যান্ডস ; সর্বজনীন সরল ইন-ক্লাস পদ্ধতির ('সাধারণ' স্ক্রিপ্টের জন্য কেবল নিজেকে সরিয়ে ফেলুন ):

ফাংশন রঙ:

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

আমি বুঝতে পারি এই প্রশ্নটি পুরানো তবে আমি আনতকের উত্তর বুঝতে পারি নি এবং লাইব্রেরিটি ব্যবহার করতে চাইনি তাই আমি নিজের সমাধানটি ঘুরিয়ে ফেললাম।

সমাধানটি রেকর্ডগুলি 2D অ্যারে, রেকর্ডগুলি সমস্ত একই দৈর্ঘ্যের এবং ক্ষেত্রগুলি সমস্ত স্ট্রিং are

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
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.