简体   繁体   中英

maximum length of a column in a list of lists

Given the example of a list of lists:

['| A   | B   |\n| CCC | DDD |\n'])

how can I find the max column width for every column, to print it out as a 2D-table as such, with all the correct spaces in between.

| A   | B   |
| CCC | DDD |

From the example that the OP is showing in the question, actually it seems that the table is encoded in a string, where columns are divided by '|'and rows are divided by '\\n'.

Given this setup (please, OP, fix it in the question), one possible way, after converting the table from string to actual list of lists, is to iterate every each row and identify the length of each element in each column and change the sizes accordingly. Then, print every element of the table with the information about the width of each column.

In the following, functions implementing the general description of the algorithm are (the different aspects are broken down for modularity and for making the learning easier for the OP):

  • Transformation of the table in string format to list of lists, namely list of rows, and each row contains a string with the actual element at a given column:

     def transform_string_to_list_of_lists(input_string): rows = input_string.strip().split('\\n') list_of_lists = [] last_size = 0 for i, row in enumerate(rows): row_list = [col.strip() for col in row[1:-2].split('|')] if i == 0: last_size = len(row_list) else: if len(row_list) != last_size: print("Not a matrix") return None list_of_lists.append(row_list) return list_of_lists

    There are three different components to pay attention to in this function:

    • the string is stripped of the last '\\n' as otherwise it would result in an extra empty row;
    • the row string is stripped of the first and last '|', and also each element is stripped of whitespaces;
    • there is a check on whether the number of columns in each row is the same or not.
  • Find the maximum width of each column, which returns a list, whose size is the number of columns, and that contains the maximum width for each column:

     def find_each_column_width(input_table): columns_size = [0] * len(input_table[0]) for row in input_table: for j, column_element in enumerate(row): columns_size[j] = max(columns_size[j], len(column_element)) return columns_size

    Note the way that columns_size is initialized. Also note that the check about the consistency of the table is done when the list of lists is actually created.

  • Return the string containing the formatted table:

     def print_formatted_table(input_table, columns_width): output_table_string = "" for row in input_table: for i, element in enumerate(row): output_table_string = output_table_string + "| " + element.ljust(columns_width[i]) output_table_string += " |\\n" return output_table_string

    Note ljust adds some trailing spaces to the string.

An example of calling of such functions is:

if __name__ == "__main__":       
    input_table_in_string = '| A | B |\n| CCC | DDD |\n'
    input_table = transform_string_to_list_of_lists(input_table_in_string)
    columns_width = find_each_column_width(input_table)
    print(print_formatted_table(input_table, columns_width))

which results in the following output:

| A  | B   |
| CCC| DDD |

Note that if a list of tables is provided, then it is sufficient to iterate through that list and calling such functions to print them properly.

Given example in your question is not the list of lists. you can check this question to create the list of lists

Python: list of lists

You can print out the string in this way:

d = []
d.append('| A   | B   |\n| CCC | DDD |\n')

col = d[0].split('\n')
temp=0
string =""
for i in col:
    print i

Split the string from '\\n' store it in an array and print out the elements of array.

You could use something like the following script:

import csv
import StringIO


def write_cols(data, col_spacer='|'):
    widths = [0] * len(data[0])

    for row in data:
        widths[:] = [max(widths[index], len(str(col))) for index, col in enumerate(row)]

    return [col_spacer + col_spacer.join("{:<{width}}".format(col, width=widths[index]) for index, col in enumerate(row)) + col_spacer for row in data]


col_data = ['| A | B |\n| CCC | DDD |\n']
rows = col_data[0].split('\n')
cells = []

for row in csv.reader(rows, delimiter='|'):
    if len(row):
        cells.append([cell.strip() for cell in row[1:-1]])

for row in write_cols(cells):
    print row

This works in two parts, firstly it strips of all the padding from the original data to create a proper list of lists in the form [['A', 'B'], ['CCC', 'DDD']] . This is then passed to write_cols() which returns the data correctly padded based on the maximum width of each column. Giving you the following kind of output:

|A  |B  |
|CCC|DDD|

Changing it write_cols(cells, " | ") would give you:

 | A   | B   | 
 | CCC | DDD |

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM