2016-03-20 4 views
-3

Учитывая пример списка списков:максимальная длина столбца в списке списков

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

как я могу найти ширину макс столбцов для каждого столбца, чтобы распечатать его в виде 2D-таблицы как таковой, со всеми правильными промежутками между ними.

| A | B | 
| CCC | DDD | 
+1

На примере вы дали не список списков. Пожалуйста, исправьте это заявление. – Rockybilly

ответ

1

Данный пример в вашем вопросе не является списком списков. Вы можете проверить этот вопрос, чтобы создать список списков

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 

Split строки из «\ п» хранить его в массив и распечатать элементы массива.

2

Из примера, который OP показывает в вопросе, на самом деле кажется, что таблица закодирована в строке, где столбцы делятся на '|' и строки делятся на '\ n'.

Учитывая эту настройку (пожалуйста, ОП, исправьте ее в вопросе), одним из возможных способов, после преобразования таблицы из строки в фактический список списков, является итерация каждой строки и идентификация длины каждого элемента в каждом и измените размеры соответственно. Затем напечатайте каждый элемент таблицы с информацией о ширине каждого столбца.

В дальнейшем функции, реализующие общее описание алгоритма (различные аспекты разбиты на модульности и сделать обучение более легким для 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 | 

Обратите внимание, что если список таблиц обеспечивается, то достаточно для повторения этого списка и вызова таких функций для правильной печати.

+0

Это отличный ответ (я считаю, что это, вероятно, то, что задавал начальный вопрос): описательные имена переменных, хорошее использование встроенной функции enumerate. Очень хорошо написано. –

1

Вы могли бы использовать что-то вроде следующего сценария:

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 | 
Смежные вопросы