Управление выводом таблицы, модуль prettytable в Python
Модуль prettytable позволяет управлять выводом таблицы, например можно ограничить вывод только теми полями или строками, которые необходимы к просмотру.
Создадим таблицу с которой будем работать:
from prettytable import PrettyTable mytable = PrettyTable() mytable.field_names = ["City name", "Area", "Population", "Annual Rainfall"] mytable.add_rows( [ ["Adelaide", 1295, 1158259, 600.5], ["Brisbane", 5905, 1857594, 1146.4], ["Darwin", 112, 120900, 1714.7], ["Hobart", 1357, 205556, 619.5], ] )
Управление выводом данных таблицы осуществляется методом PrettyTable.get_string() .
Управление выводом колонок.
Аргумент fields метода PrettyTable.get_string() принимает список имен полей, которые нужно напечатать:
>>> table = mytable.get_string(fields=["City name", "Population"]) >>> print(table) #+-----------+------------+ #| City name | Population | #+-----------+------------+ #| Adelaide | 1158259 | #| Brisbane | 1857594 | #| Darwin | 120900 | #| Hobart | 205556 | #+-----------+------------+
Управление выводом строк.
Аргументы start и end метода PrettyTable.get_string() принимают индекс первой и последней строки для печати соответственно.
Обратите внимание, что индексация работает так же, как срезы списка Python — для печати 3-й и 4-й строк таблицы установите start равным 2 (первая строка — это строка 0, поэтому третья — это строка 2) и установите end на 4 (индекс 4-ой строки, плюс 1):
>>> table = mytable.get_string(start=2, end=4) >>> print(table) #+-----------+------+------------+-----------------+ #| City name | Area | Population | Annual Rainfall | #+-----------+------+------------+-----------------+ #| Darwin | 112 | 120900 | 1714.7 | #| Hobart | 1357 | 205556 | 619.5 | #+-----------+------+------------+-----------------+
Управление сортировкой данных в таблице.
Аргументы sortby метода PrettyTable.get_string() , который принимает строку с именем одного поля, отсортирует данный столбец таблицы по возрастанию (от меньшего к большему).
>>> table = mytable.get_string(sortby='Area') >>> print(table) #+-----------+------+------------+-----------------+ #| City name | Area | Population | Annual Rainfall | #+-----------+------+------------+-----------------+ #| Darwin | 112 | 120900 | 1714.7 | #| Adelaide | 1295 | 1158259 | 600.5 | #| Hobart | 1357 | 205556 | 619.5 | #| Brisbane | 5905 | 1857594 | 1146.4 | #+-----------+------+------------+-----------------+
Если необходимо отсортировать в обратном порядке, то в метод нужно добавить ключевой аргумент reversesort=True .
>>> table = mytable.get_string(sortby='Area', reversesort=True) >>> print(table) #+-----------+------+------------+-----------------+ #| City name | Area | Population | Annual Rainfall | #+-----------+------+------------+-----------------+ #| Brisbane | 5905 | 1857594 | 1146.4 | #| Hobart | 1357 | 205556 | 619.5 | #| Adelaide | 1295 | 1158259 | 600.5 | #| Darwin | 112 | 120900 | 1714.7 | #+-----------+------+------------+-----------------+
Если необходимо, чтобы таблицы сортировались всегда определенным образом, то можно сделать этот параметр долгосрочным при помощи атрибута экземпляра класса PrettyTable.sortby :
# сортировка по колонке `Population` >>> mytable.sortby = "Population" # отсортирует вывод по колонке `Population` >>> print(mytable)
Теперь, команда print(mytable) напечатает таблицу, отсортированную по колонке Population . Также, при помощи атрибута mytable.reversesort = True можно сортировать таблицу по колонке, указанной в mytable.sortby — в обратном порядке. Такое поведение будет сохраняться, пока не отключить сортировку атрибутом x.sortby = None .
# отключение сортировки >>> mytable.sortby = None # выведет таблицу в исходном виде >>> print(mytable)
Если нужно указать пользовательскую функцию сортировки, то можно использовать ключевой аргумент sort_key .
Передайте аргументу sort_key функцию, которая принимает два списка значений и возвращает отрицательное или положительное значение в зависимости от того, должен ли первый список появляться до или после второго. Если в таблице n столбцов, то в каждом списке будет n + 1 элемент. Каждый список соответствует одной строке таблицы. Первым элементом будут данные из соответствующей строки в столбце, заданном аргументом sort_by . Остальные n элементов — это данные в каждом столбце таблицы по порядку, включая повторяющийся экземпляр данных в столбце sort_by .
- КРАТКИЙ ОБЗОР МАТЕРИАЛА.
- Печать табличных данных в файл, модуль prettytable
- Удаление данных из таблицы, модуль prettytable
- Управление выводом таблицы, модуль prettytable
- Управление внешним видом таблицы, модуль prettytable
- Генерация HTML и JSON при помощи prettytable
Как напечатать таблицу с помощью 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 el in data: for col in el: print(f'>', end='') print()
Здесь в 4 строке кода, после : указана ширина колонок. Так как это не число, а выражение, его обрамляют фигурными скобками. Ширину колонок мы сделали по максимальной длине строки колонок и добавили еще один символ пустой строки » для отступов, end=» – указывает, что печать будет выводиться без переноса на новую строку. Выравнивание текста в строке по умалчиванию делается по левому краю, поэтому его не указываем. Далее будут рассмотрены все виды выравнивания.
Недостатки такой таблицы:
- большая ширина (подходит для таблиц с примерно одинаковой длинной строк колонок);
- трудно вычислить длину разделителя шапки.
Таблица с разной шириной колонок
Рассмотрим другой пример. Выведем таблицу с колонками максимальной длины строки каждого столбца.
# вывод таблицы с колонками максимальной длинны строки каждого столбца # печать шапки таблицы for n, column in enumerate(columns): print(f'>', end='') print() # печать разделителя шапки '=' r = f'' print(r[:-1]) # печать тела таблицы for el in data: for n, col in enumerate(el): print(f'>', 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'>', end='') print() # печать разделителя шапки '=' print(f"") # печать тела таблицы for el in data: for n, col in enumerate(el): print(f'>', 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) >', 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. В любом случае не очень понятно, что требуется. Если надо просто вывести содержимое этих тегов то гугли про парсинг вложенных тегов, смотри методы в документации бс. Ну а если не получится найти и кто-то другой не ответит, то вечером, как приду домой — отвечу я, с телефона не очень.
Дмитрий @ipatov_dn Автор вопроса
javedimka: в краце есть кусок html в итоге надо вывести как я понимаю словарь th[0]:td[0] и так далее но чето цыкл против меня пока что тк я неопытен и только учусь питону
Решения вопроса 2
Самый простой способ с помощью 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 | +-------------------+---------------+------+-------------+------------+
А теперь представь сколько бесполезных разговоров могло быть опущено и времени сэкономлено, если бы у тебя с первого раза получилось нормально вопрос сформулировать? Вот то-то и оно.
Как вывести таблицу в python
Часто в задачах приходится хранить прямоугольные таблицы с данными. Такие таблицы называются матрицами или двумерными массивами. В языке программирования Питон таблицу можно представить в виде списка строк, каждый элемент которого является в свою очередь списком, например, чисел. Например, приведём программу, в которой создаётся числовая таблица из двух строк и трех столбцов, с которой производятся различные действия.
a = [[1, 2, 3], [4, 5, 6]] print(a[0]) print(a[1]) b = a[0] print(b) print(a[0][2]) a[0][1] = 7 print(a) print(b) b[2] = 9 print(a[0]) print(b)
Здесь первая строка списка a[0] является списком из чисел [1, 2, 3] . То есть a[0][0] == 1 , значение a[0][1] == 2 , a[0][2] == 3 , a[1][0] == 4 , a[1][1] == 5 , a[1][2] == 6 .
Для обработки и вывода списка, как правило, используют два вложенных цикла. Первый цикл перебирает номер строки, второй цикл бежит по элементам внутри строки. Например, вывести двумерный числовой список на экран построчно, разделяя числа пробелами внутри одной строки, можно так:
a = [[1, 2, 3, 4], [5, 6], [7, 8, 9]] for i in range(len(a)): for j in range(len(a[i])): print(a[i][j], end=' ') print()
Однажды мы уже пытались объяснить, что переменная цикла for в Питоне может перебирать не только диапазон, создаваемый с помощью функции range() , но и вообще перебирать любые элементы любой последовательности. Последовательностями в Питоне являются списки, строки, а также некоторые другие объекты, с которыми мы пока не встречались. Продемонстрируем, как выводить двумерный массив, используя это удобное свойство цикла for :
a = [[1, 2, 3, 4], [5, 6], [7, 8, 9]] for row in a: for elem in row: print(elem, end=' ') print()
Естественно, для вывода одной строки можно воспользоваться методом join() :
for row in a: print(' '.join([str(elem) for elem in row]))
Используем два вложенных цикла для подсчета суммы всех чисел в списке:
a = [[1, 2, 3, 4], [5, 6], [7, 8, 9]] s = 0 for i in range(len(a)): for j in range(len(a[i])): s += a[i][j] print(s)
Или то же самое с циклом не по индексу, а по значениям строк:
a = [[1, 2, 3, 4], [5, 6], [7, 8, 9]] s = 0 for row in a: for elem in row: s += elem print(s)
2. Создание вложенных списков
Пусть даны два числа: количество строк n и количество столбцов m . Необходимо создать список размером n × m , заполненный нулями.
Очевидное решение оказывается неверным:
a = [[0] * m] * n
В этом легко убедиться, если присвоить элементу a[0][0] значение 5 , а потом вывести значение другого элемента a[1][0] — оно тоже будет равно 5. Дело в том, что [0] * m возвращает ccылку на список из m нулей. Но последующее повторение этого элемента создает список из n элементов, которые являются ссылкой на один и тот же список (точно так же, как выполнение операции b = a для списков не создает новый список), поэтому все строки результирующего списка на самом деле являются одной и той же строкой.
В визуализаторе обратите внимание на номер id у списков. Если у двух списков id совпадает, то это на самом деле один и тот же список в памяти.
n = 3 m = 4 a = [[0] * m] * n a[0][0] = 5 print(a[1][0])
Таким образом, двумерный список нельзя создавать при помощи операции повторения одной строки. Что же делать?
Первый способ: сначала создадим список из n элементов (для начала просто из n нулей). Затем сделаем каждый элемент списка ссылкой на другой одномерный список из m элементов:
n = 3 m = 4 a = [0] * n for i in range(n): a[i] = [0] * m
Другой (но похожий) способ: создать пустой список, потом n раз добавить в него новый элемент, являющийся списком-строкой:
n = 3 m = 4 a = [] for i in range(n): a.append([0] * m)
Но еще проще воспользоваться генератором: создать список из n элементов, каждый из которых будет списком, состоящих из m нулей:
n = 3 m = 4 a = [[0] * m for i in range(n)]
В этом случае каждый элемент создается независимо от остальных (заново конструируется список [0] * m для заполнения очередного элемента списка), а не копируются ссылки на один и тот же список.
3. Ввод двумерного массива
Пусть программа получает на вход двумерный массив в виде n строк, каждая из которых содержит m чисел, разделенных пробелами. Как их считать? Например, так:
3 1 2 3 4 5 6 7 8 9
# в первой строке ввода идёт количество строк массива n = int(input()) a = [] for i in range(n): a.append([int(j) for j in input().split()])
Или, без использования сложных вложенных вызовов функций:
3 1 2 3 4 5 6 7 8 9
# в первой строке ввода идёт количество строк массива n = int(input()) a = [] for i in range(n): row = input().split() for i in range(len(row)): row[i] = int(row[i]) a.append(row)
Можно сделать то же самое и при помощи генератора:
3 1 2 3 4 5 6 7 8 9
# в первой строке ввода идёт количество строк массива n = int(input()) a = [[int(j) for j in input().split()] for i in range(n)]
4. Пример обработки двумерного массива
Пусть дан квадратный массив из n строк и n столбцов. Необходимо элементам, находящимся на главной диагонали, проходящей из левого верхнего угла в правый нижний (то есть тем элементам a[i][j] , для которых i==j ) присвоить значение 1 , элементам, находящимся выше главной диагонали – значение 0, элементам, находящимся ниже главной диагонали – значение 2. То есть необходимо получить такой массив (пример для n==4 ):
1 0 0 0 2 1 0 0 2 2 1 0 2 2 2 1
Рассмотрим несколько способов решения этой задачи. Элементы, которые лежат выше главной диагонали – это элементы a[i][j] , для которых ij . Таким образом, мы можем сравнивать значения i и j и по ним определять значение A[i][j] . Получаем следующий алгоритм:
n = 4 a = [[0] * n for i in range(n)] for i in range(n): for j in range(n): if i < j: a[i][j] = 0 elif i >j: a[i][j] = 2 else: a[i][j] = 1 for row in a: print(' '.join([str(elem) for elem in row]))
Данный алгоритм плох, поскольку выполняет одну или две инструкции if для обработки каждого элемента. Если мы усложним алгоритм, то мы сможем обойтись вообще без условных инструкций.
Сначала заполним главную диагональ, для чего нам понадобится один цикл:
for i in range(n): a[i][i] = 1
Затем заполним значением 0 все элементы выше главной диагонали, для чего нам понадобится в каждой из строк с номером i присвоить значение элементам a[i][j] для j = i+1 , . n-1 . Здесь нам понадобятся вложенные циклы:
for i in range(n): for j in range(i + 1, n): a[i][j] = 0
Аналогично присваиваем значение 2 элементам a[i][j] для j = 0 , . i-1 :
for i in range(n): for j in range(0, i): a[i][j] = 2
Можно также внешние циклы объединить в один и получить еще одно, более компактное решение:
n = 4 a = [[0] * n for i in range(n)] for i in range(n): for j in range(0, i): a[i][j] = 2 a[i][i] = 1 for j in range(i + 1, n): a[i][j] = 0 for row in a: print(' '.join([str(elem) for elem in row]))
А вот такое решение использует операцию повторения списков для построения очередной строки списка. i -я строка списка состоит из i чисел 2 , затем идет одно число 1 , затем идет n-i-1 число 0 :
n = 4 a = [0] * n for i in range(n): a[i] = [2] * i + [1] + [0] * (n - i - 1) for row in a: print(' '.join([str(elem) for elem in row]))
А можно заменить цикл на генератор:
n = 4 a = [0] * n a = [[2] * i + [1] + [0] * (n - i - 1) for i in range(n)] for row in a: print(' '.join([str(elem) for elem in row]))
5. Вложенные генераторы двумерных массивов
Для создания двумерных массивов можно использовать вложенные генераторы, разместив генератор списка, являющегося строкой, внутри генератора всех строк. Напомним, что сделать список из n строк и m столбцов можно при помощи генератора, создающего список из n элементов, каждый элемент которого является списком из m нулей:
[[0] * m for i in range(n)]
Но при этом внутренний список также можно создать при помощи, например, такого генератора: [0 for j in range(m)] . Вложив один генератор в другой, получим вложенные генераторы:
[[0 for j in range(m)] for i in range(n)]
Но если число 0 заменить на некоторое выражение, зависящее от i (номер строки) и j (номер столбца), то можно получить список, заполненный по некоторой формуле.
Например, пусть нужно задать следующий массив (для удобства добавлены дополнительные пробелы между элементами):
0 0 0 0 0 0 0 1 2 3 4 5 0 2 4 6 8 10 0 3 6 9 12 15 0 4 8 12 16 20
В этом массиве n = 5 строк, m = 6 столбцов, и элемент в строке i и столбце j вычисляется по формуле: a[i][j] = i * j .
Для создания такого массива можно использовать генератор:
[[i * j for j in range(m)] for i in range(n)]