Python - Print list of CSV strings in aligned colu

2019-02-26 07:58发布

问题:

I have written a fragment of code that is fully compatible with both Python 2 and Python 3. The fragment that I wrote parses data and it builds the output as a list of CSV strings.

The script provides an option to:

  • write the data to a CSV file, or
  • display it to the stdout.

While I could easily iterate through the list and replace , with \t when displaying to stdout (second bullet option), the items are of arbitrary length, so don't line up in a nice format due to variances in tabs.

I have done quite a bit of research, and I believe that string format options could accomplish what I'm after. That said, I can't seem to find an example that helps me get the syntax correct.

I would prefer to not use an external library. I am aware that there are many options available if I went that route, but I want the script to be as compatible and simple as possible.

Here is an example:

value1,somevalue2,value3,reallylongvalue4,value5,superlongvalue6
value1,value2,reallylongvalue3,value4,value5,somevalue6

Can you help me please? Any suggestion will be much appreciated.

回答1:

import csv
from StringIO import StringIO

rows = list(csv.reader(StringIO(
    '''value1,somevalue2,value3,reallylongvalue4,value5,superlongvalue6
value1,value2,reallylongvalue3,value4,value5,somevalue6''')))

widths = [max(len(row[i]) for row in rows) for i in range(len(rows[0]))]

for row in rows:
    print(' | '.join(cell.ljust(width) for cell, width in zip(row, widths)))

Output:

value1 | somevalue2 | value3           | reallylongvalue4 | value5 | superlongvalue6
value1 | value2     | reallylongvalue3 | value4           | value5 | somevalue6     


回答2:

def printCsvStringListAsTable(csvStrings):

    # convert to list of lists
    csvStrings = map(lambda x: x.split(','), csvStrings)

    # get max column widths for printing
    widths = []
    for idx in range(len(csvStrings[0])):
        columns = map(lambda x: x[idx], csvStrings)
        widths.append(
            len(
                max(columns, key = len)
            )
        )

    # print the csv strings
    for row in csvStrings:
        cells = []
        for idx, col in enumerate(row):
            format = '%-' + str(widths[idx]) + "s"
            cells.append(format % (col))
        print ' |'.join(cells)


if __name__ == '__main__':
    printCsvStringListAsTable([
        'col1,col2,col3,col4',
        'val1,val2,val3,val4',
        'abadfafdm,afdafag,aadfag,aadfaf',
    ])

Output:

col1      |col2    |col3   |col4
val1      |val2    |val3   |val4
abadfafdm |afdafag |aadfag |aadfaf

The answer by Alex Hall is definitely better and a terse form of the same code which I have written.