【问题标题】:maximum length of a column in a list of lists列表列表中列的最大长度
【发布时间】:2016-03-21 06:28:07
【问题描述】:

以列表列表为例:

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

如何找到每列的最大列宽,将其打印为二维表,中间包含所有正确的空格。

| A   | B   |
| CCC | DDD |

【问题讨论】:

  • 您给出的示例不是列表。请更正这两种说法。

标签: python string formatting


【解决方案1】:

从问题中显示的 OP 示例来看,实际上似乎表格是用字符串编码的,其中列用“|”分隔并且行被'\n'分割。

鉴于此设置(请OP,在问题中修复它),在将表格从字符串转换为实际列表列表之后,一种可能的方法是迭代每一行并确定每列中每个元素的长度并相应地更改尺寸。然后,打印表格的每个元素以及每列的宽度信息。

在下文中,实现算法的一般描述的函数是(为了模块化和使 OP 更容易学习,对不同方面进行了分解):

  • 将字符串格式的表格转换为列表列表,即行列表,每行包含一个字符串,该字符串具有给定列的实际元素:

    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
    

    在这个函数中需要注意三个不同的组件:

    • 字符串被去掉最后一个 '\n' 否则会导致额外的空行;
    • 行字符串的第一个和最后一个“|”被去除,每个元素也被去除空格;
    • 检查每行的列数是否相同。
  • 求每列的最大宽度,返回一个列表,其大小为列数,其中包含每列的最大宽度:

    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
    

    注意columns_size 的初始化方式。另请注意,在实际创建列表列表时会检查表的一致性。

  • 返回包含格式化表格的字符串:

    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
    

    注意ljust 在字符串后面添加一些空格。

调用此类函数的一个例子是:

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

导致以下输出:

| A  | B   |
| CCC| DDD |

请注意,如果提供了一个表列表,那么遍历该列表并调用此类函数以正确打印它们就足够了。

【讨论】:

  • 这是一个很好的答案(我相信这可能是最初的问题要问的):描述性变量名称,很好地使用 enumerate 内置函数。写的很好。
【解决方案2】:

您问题中的示例不是列表列表。您可以检查此问题以创建列表列表

Python: list of lists

可以这样打印出字符串:

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

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

从 '\n' 中拆分字符串存储到一个数组中并打印出数组的元素。

【讨论】:

    【解决方案3】:

    你可以使用类似下面的脚本:

    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
    

    这分两部分工作,首先它从原始数据中去除所有填充以创建[['A', 'B'], ['CCC', 'DDD']] 形式的正确列表列表。然后将其传递给write_cols(),它根据每列的最大宽度返回正确填充的数据。为您提供以下类型的输出:

    |A  |B  |
    |CCC|DDD|
    

    更改它write_cols(cells, " | ") 会给你:

     | A   | B   | 
     | CCC | DDD |
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-30
      • 1970-01-01
      • 2013-01-16
      • 1970-01-01
      相关资源
      最近更新 更多