Как напечатать таблицу с помощью f-string
В этой статье мы разберём как напечатать красивые таблицы:
- с одинаковой шириной колонок;
- с разной шириной колонок;
- с шапкой из двух строк.
«F-строки» были введены ещё в версии Python 3.6, и все уже давно, наверно, их используют в своём коде. Для тех, кто хочет освежить память, и ещё раз перечитать документацию — PEP 498 — Literal String Interpolation. Мы же будем использовать «f-строки» для вывода данных в табличном виде. Для примера возьмём данные об автомобилях с одного из онлайн-рынков такой структуры:
data = [ ['Volkswagen', 'Golf V', '2008', '8000', '154000'], ['Mazda', 'CX-5', '2013', '14800', '117000'], ['Honda', 'CR-V AWD', '2017', '22000', '57000'], ['BMW', '320', '2015', '14700', '124000'], ['BMW', 'X1', '2012', '17000', '62000'], ['Mercedes-Benz', 'E 220', '2009', '9300', '240000'], ['Volkswagen', 'Golf VI STYLE', '2011', '9700', '203000'], ['Mazda', '6', '2006', '5600', '218000'], ['Hyundai', 'Tucson LOUNGE 2009', '2008', '8899', '149000'], ['BMW', '520', '2013', '21700', '146000'], ['Toyota', 'Highlander', '2015', '28000', '120000'], ['Mercedes-Benz', 'E 220', '2005', '8200', '276000'], ['BMW', '328', '2012', '12500', '260000'], ['Opel', 'Astra J', '2013', '9500', '224000'], ['Volkswagen', 'Passat B7', '2013', '11750', '138000'], ['Audi', 'A6 Quattro', '2006', '8000', '28000'] ]
columns = ['Марка', 'Модель', 'Год', 'Цена', 'Пробег']
Таблица с одинаковой шириной колонок
Для того, чтоб данные в колонках таблицы выровнять по центру, левому или правому краю, нужно рассчитать ширину колонок и определить отступ. Давайте сделаем ширину колонок одинаковой по максимальной строке столбца и отступом в один символ.
# расчёт максимальной длинны колонок 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'>', end='') print() # печать разделителя шапки print(f'
Недостатки такой таблицы:
- большая ширина (подходит для таблиц с примерно одинаковой длинной строк колонок);
- трудно вычислить длину разделителя шапки.
Таблица с разной шириной колонок
Рассмотрим другой пример. Выведем таблицу с колонками максимальной длины строки каждого столбца.
# вывод таблицы с колонками максимальной длинны строки каждого столбца # печать шапки таблицы for n, column in enumerate(columns): print(f'>', end='') print() # печать разделителя шапки '=' r = f'![Python красиво вывести таблицу]()
Теперь таблица стала компактнее.
В этом примере названия колонок меньше или равны ширине самих колонок. А что, если они будут больше? Например, состоять из двух слов.
Таблица с шапкой из двух строк
Если ширина названия колонок больше ширины колонок тела таблицы, тогда запишем их в шапке таблицы в две строчки — вот так:
![Python красиво вывести таблицу]()
Но теперь колонки названий могут быть шире рассчитанных ранее колонок тела таблицы. Придётся отдельно просчитать максимальные значения ширины колонок шапки и максимальные значения колонок тела таблицы, сравнить их и по большему значению задать ширину столбиков для всей таблицы.
# пишем название колонок в две строчки 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'>', end='') print() # печать разделителя шапки '=' print(f"") # печать тела таблицы for el in data: for n, col in enumerate(el): print(f'>', end='') print() print()
Tech Lead/Senior Python developer на продукт Data Quality (DataOps Platform) МТС , Москва, можно удалённо , По итогам собеседования

Функция с параметром максимальной ширины таблицы
Давайте соберём наш код в функцию, но добавим ещё один параметр — максимальную ширину таблицы. И если ширина таблицы будет больше максимальной, заданной по умалчиванию — выведем сообщение. А также сделаем выравнивание текста в строках шапки таблицы по центру, в теле таблицы — по правому краю. Для этого надо всего лишь перед значением ширины строки вставить символ «^» — выравнивание по центру, «>» — выравнивание по правому краю, «
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) >', end='') # выравниване по ценру else: print('Ширина таблицы больше допустимого значения') return print() # печать разделителя шапки '=' print(f"") # печать тела таблицы for el in data: for n, col in enumerate(el): print(f'>', 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) >', end='') # выравниване по ценру else: print('Ширина таблицы больше допустимого значения') return print() # печать разделителя шапки '=' print(f"") # печать тела таблицы for el in data: for n, col in enumerate(el): if n < 3: print(f'>', end='') # выравнвание по правому краю else: print(f'', end='') # выравнвание по правому краю наследуется, с разделителем тысяч «,» print()
Здесь, в 52 строке кода, в f',> ‘ перед закрывающей фигурной скобкой вставлена запятая, как разделитель тысяч (кроме «,» можно ещё использовать «_»), ну а дальше форматирование сделает всё само:

Но это ещё не все возможности «спецификации формата».
Примечание: в 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) >') else: print('Ширина таблицы больше допустимого значения') return f.write('\n')
Как в Python сделать вывод таблицей?

javedimka: h2 = wifi.find_all('h2') посмотрите пожалуйста внимательно html код или вы только обратили внимаение на не правильно сформулированную суть вопроса?
Дмитрий: Хтмл не смотрел, зачем? Что-то было в твоем вопросе и это что-то заставило мня написать про find_all. В любом случае не очень понятно, что требуется. Если надо просто вывести содержимое этих тегов то гугли про парсинг вложенных тегов, смотри методы в документации бс. Ну а если не получится найти и кто-то другой не ответит, то вечером, как приду домой - отвечу я, с телефона не очень.

javedimka: в краце есть кусок html в итоге надо вывести как я понимаю словарь th[0]:td[0] и так далее но чето цыкл против меня пока что тк я неопытен и только учусь питону
Самый простой способ с помощью Python вывести таблицу с данными в терминале или cmd это установить какой-нибудь модуль для ascii таблиц, например: PrettyTable
$ pip install PrettyTable
from prettytable import PrettyTable # Импортируем установленный модуль. # Определяем твою шапку и данные. th = [. ] td = [. ] columns = len(th) # Подсчитаем кол-во столбцов на будущее. table = PrettyTable(th) # Определяем таблицу. # Cкопируем список td, на случай если он будет использоваться в коде дальше. td_data = td[:] # Входим в цикл который заполняет нашу таблицу. # Цикл будет выполняться до тех пор пока у нас не кончатся данные # для заполнения строк таблицы (список td_data). while td_data: # Используя срез добавляем первые пять элементов в строку. # (columns = 5). table.add_row(td_data[:columns]) # Используя срез переопределяем td_data так, чтобы он # больше не содержал первых 5 элементов. td_data = td_data[columns:] print(table) # Печатаем таблицу
+-------------------+---------------+------+-------------+------------+ | MAC Address | IP Address | Mode | Rate (Mbps) | Signal (%) | +-------------------+---------------+------+-------------+------------+ | 11:11:11:11:11:11 | 192.168.0.103 | 11n | 65 | 100 | | 11:11:11:11:11:11 | 192.168.0.103 | 11n | 65 | 100 | | 11:11:11:11:11:11 | 192.168.0.103 | 11n | 65 | 100 | | 11:11:11:11:11:11 | 192.168.0.103 | 11n | 65 | 100 | | 11:11:11:11:11:11 | 192.168.0.103 | 11n | 65 | 100 | +-------------------+---------------+------+-------------+------------+
А теперь представь сколько бесполезных разговоров могло быть опущено и времени сэкономлено, если бы у тебя с первого раза получилось нормально вопрос сформулировать? Вот то-то и оно.