Разберём, как напечатать красивую таблицу с одинаковой шириной колонок, с разной шириной колонок, с шапкой из двух строк. Создадим функцию с параметром максимальной ширины таблицы и функцию для записи таблицы в текстовый файл.
11К открытий12К показов
В этой статье мы разберём как напечатать красивые таблицы:
с одинаковой шириной колонок;
с разной шириной колонок;
с шапкой из двух строк.
А также создадим функции:
с параметром максимальной ширины таблицы;
для записи таблицы в текстовый файл.
«F-строки» были введены ещё в версии Python 3.6, и все уже давно, наверно, их используют в своём коде. Для тех, кто хочет освежить память, и ещё раз перечитать документацию — PEP 498 – Literal String Interpolation. Мы же будем использовать «f-строки» для вывода данных в табличном виде. Для примера возьмём данные об автомобилях с одного из онлайн-рынков такой структуры:
Для того, чтоб данные в колонках таблицы выровнять по центру, левому или правому краю, нужно рассчитать ширину колонок и определить отступ. Давайте сделаем ширину колонок одинаковой по максимальной строке столбца и отступом в один символ.
# расчёт максимальной длинны колонок
max_columns = [] # список максимальной длинны колонок
for col in zip(*data):
len_el = []
[len_el.append(len(el)) for el in col]
max_columns.append(max(len_el))
Печать таблицы:
# печать таблицы с колонками максимальной длинны строки
# печать шапки таблицы
for column in columns:
print(f'{column:{max(max_columns)+1}}', end='')
print()
# печать разделителя шапки
print(f'{"="*max(max_columns)*5}')
# печать тела таблицы
for el in data:
for col in el:
print(f'{col:{max(max_columns)+1}}', end='')
print()
Здесь в 4 строке кода, после : указана ширина колонок. Так как это не число, а выражение, его обрамляют фигурными скобками. Ширину колонок мы сделали по максимальной длине строки колонок и добавили еще один символ пустой строки '' для отступов, end='' – указывает, что печать будет выводиться без переноса на новую строку. Выравнивание текста в строке по умалчиванию делается по левому краю, поэтому его не указываем. Далее будут рассмотрены все виды выравнивания.
Результат:
Недостатки такой таблицы:
большая ширина (подходит для таблиц с примерно одинаковой длинной строк колонок);
трудно вычислить длину разделителя шапки.
Таблица с разной шириной колонок
Рассмотрим другой пример. Выведем таблицу с колонками максимальной длины строки каждого столбца.
# вывод таблицы с колонками максимальной длинны строки каждого столбца
# печать шапки таблицы
for n, column in enumerate(columns):
print(f'{column:{max_columns[n]+1}}', end='')
print()
# печать разделителя шапки '='
r = f'{"="*sum(max_columns)+"="*5}'
print(r[:-1])
# печать тела таблицы
for el in data:
for n, col in enumerate(el):
print(f'{col:{max_columns[n]+1}}', end='') # выравнвание по правому краю >
print()
Результат:
Теперь таблица стала компактнее.
В этом примере названия колонок меньше или равны ширине самих колонок. А что, если они будут больше? Например, состоять из двух слов.
Таблица с шапкой из двух строк
Если ширина названия колонок больше ширины колонок тела таблицы, тогда запишем их в шапке таблицы в две строчки — вот так:
Но теперь колонки названий могут быть шире рассчитанных ранее колонок тела таблицы. Придётся отдельно просчитать максимальные значения ширины колонок шапки и максимальные значения колонок тела таблицы, сравнить их и по большему значению задать ширину столбиков для всей таблицы.
# пишем название колонок в две строчки
columns = [['Марка', 'Модель', 'Год', 'Цена $', 'Пробег км'],
['автомобиля', '', 'выпуска', '', '']]
# вычислить максимальную длинну колонки шапки таблицы
max_columns_title = [] # список максимальной ширины колонок шапки
for col in zip(*columns):
max_columns_title.append(max([len(el) for el in col]))
max_col_title = max(max_columns_title) # максимальная ширина колонки шапки
for col in columns:
#width = []
for n, c in enumerate(col):
# сравниваем максимальную колонку шапки с макс колонкой таблицы
if max_columns[n] >= max_columns_title[n]:
w = max_columns[n] + 2
width.append(w)
else:
w = max_columns_title[n] + 2
width.append(w)
# пишем название колонок в две строчки
print(f'{c:{w}}', end='')
print()
# печать разделителя шапки '='
print(f"{'='*(sum(width)-2)}")
# печать тела таблицы
for el in data:
for n, col in enumerate(el):
print(f'{col:{width[n]}}', end='')
print()
print()
Результат:
Функция с параметром максимальной ширины таблицы
Давайте соберём наш код в функцию, но добавим ещё один параметр — максимальную ширину таблицы. И если ширина таблицы будет больше максимальной, заданной по умалчиванию — выведем сообщение. А также сделаем выравнивание текста в строках шапки таблицы по центру, в теле таблицы — по правому краю. Для этого надо всего лишь перед значением ширины строки вставить символ «^» — выравнивание по центру, «>» — выравнивание по правому краю, «<» – выравнивание по левому краю, выставлено по умолчанию.
def print_table(data, columns, indent, max_width=100):
# data — список списков, данные таблицы
# columns — список списков, названия колонок таблицы
# indent — отступ от края колонки
# max_widt – допустимая ширина таблицы
# max_columns — список максимальной длинны строки колонок
# max_columns_title — список максимальной ширины колонок шапки
# width — список ширины каждой колонки таблицы для печати
# расчёт макимальной ширины колонок таблицы
max_columns = []
for col in zip(*data):
len_el = []
[len_el.append(len(el)) for el in col]
max_columns.append(max(len_el))
# вычислить максимальную длинну колонки шапки таблицы
max_columns_title = []
for col in zip(*columns):
max_columns_title.append(max([len(el) for el in col]))
# печать таблицы
for col in columns:
width = []
for n, c in enumerate(col):
# сравниваем максимальную колонку шапки с макс колонкой таблицы
if max_columns[n] >= max_columns_title[n]:
w = max_columns[n] + indent
width.append(w)
else:
w = max_columns_title[n] + indent
width.append(w)
# пишем название колонок в две строки
if sum(width) <= max_width:
print(f'{c:^{w}}', end='') # выравниване по ценру
else:
print('Ширина таблицы больше допустимого значения')
return
print()
# печать разделителя шапки '='
print(f"{'='*(sum(width))}")
# печать тела таблицы
for el in data:
for n, col in enumerate(el):
print(f'{col:>{width[n]}}', end='') # выравнвание по правому краю
print()
print_table(data, columns, 1, max_width=100)
Результат:
Давайте ещё изменим вывод нашей таблицы. Колонки «Цена $» и «Пробег км» выведем с ,, как разделитель тысяч.
def print_table(data, columns, indent, max_width=100):
# data — список списков, данные таблицы
# columns — список списков, названия колонок таблицы
# indent — отступ от края колонки
# max_widt — допустимая ширина таблицы
# max_columns — список максимальной длинны строки колонок
# max_columns_title — список максимальной ширины колонок шапки
# width — список ширины каждой колонки таблицы для печати
# расчёт макимальной ширины колонок таблицы
max_columns = []
for col in zip(*data):
len_el = []
[len_el.append(len(el)) for el in col]
max_columns.append(max(len_el))
# вычислить максимальную длинну колонки шапки таблицы
max_columns_title = []
for col in zip(*columns):
max_columns_title.append(max([len(el) for el in col]))
# печать таблицы
for col in columns:
width = []
for n, c in enumerate(col):
# сравниваем максимальную колонку шапки с макс колонкой таблицы
if max_columns[n] >= max_columns_title[n]:
w = max_columns[n] + indent
width.append(w)
else:
w = max_columns_title[n] + indent
width.append(w)
# пишем название колонок в две строки
if sum(width) <= max_width:
print(f'{c:^{w}}', end='') # выравниване по ценру
else:
print('Ширина таблицы больше допустимого значения')
return
print()
# печать разделителя шапки '='
print(f"{'='*(sum(width))}")
# печать тела таблицы
for el in data:
for n, col in enumerate(el):
if n < 3:
print(f'{col:>{width[n]}}', end='') # выравнвание по правому краю
else:
print(f'{int(col):{width[n]},}', end='') # выравнвание по правому краю наследуется, с разделителем тысяч «,»
print()
Здесь, в 52 строке кода, в f'{int(col):{width[n]},}‘ перед закрывающей фигурной скобкой вставлена запятая, как разделитель тысяч (кроме «,» можно ещё использовать «_»), ну а дальше форматирование сделает всё само:
Но это ещё не все возможности «спецификации формата».
Примечание: в F-string в фигурных скобках {} помещены «заменяющие поля». Двоеточие : указывает на поле format_spec, что означает нестандартный формат замены. Для него существует Мини-язык спецификации формата.
Функция для записи таблицы в текстовый файл
Часто приходится не только печатать таблицу, но и сохранять её в текстовом файле. Имея готовую функцию для печати, нетрудно переделать её для записи.
def write_table(file_name, data, columns, indent, max_width=100):
# file_name — название текстового файла
# data — список списков, данные таблицы
# columns — список списков, названия колонок таблицы
# indent — отступ от края колонки
# max_widt — допустимая ширина таблицы
# max_columns — список максимальной длинны строки колонок
# max_columns_title — список максимальной ширины колонок шапки
# width — список ширины каждой колонки таблицы для печати
# расчёт макимальной ширины колонок таблицы
max_columns = []
for col in zip(*data):
len_el = []
[len_el.append(len(el)) for el in col]
max_columns.append(max(len_el))
# вычислить максимальную длинну колонки шапки таблицы
max_columns_title = []
for col in zip(*columns):
max_columns_title.append(max([len(el) for el in col]))
# запись таблицы
with open(file_name, 'w', encoding='utf-8') as f:
for col in columns:
width = []
for n, c in enumerate(col):
# сравниваем максимальную колонку шапки с макс колонкой таблицы
if max_columns[n] >= max_columns_title[n]:
w = max_columns[n] + indent
width.append(w)
else:
w = max_columns_title[n] + indent
width.append(w)
# пишем название колонок в две строки
if sum(width) <= max_width:
f.write(f'{c:^{w}}')
else:
print('Ширина таблицы больше допустимого значения')
return
f.write('\n')
Узнайте о лучших библиотеках Python, которые помогут вам в 2024 году. От анализа данных до веб-разработки — все, что нужно для эффективного программирования на Python.
Мы погрузились в мрачный мир фантазий и представили, какие языки программирования и роли могли бы выбрать самые известные злодеи хоррор-фильмов, если бы они ворвались в IT.