Как вывести матрицу в python в виде таблицы
Здесь первая строка списка 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 .
Для обработки и вывода списка, как правило, используют два вложенных цикла. Первый цикл перебирает номер строки, второй цикл бежит по элементам внутри строки. Например, вывести двумерный числовой список на экран построчно, разделяя числа пробелами внутри одной строки, можно так:
Однажды мы уже пытались объяснить, что переменная цикла for в Питоне может перебирать не только диапазон, создаваемый с помощью функции range() , но и вообще перебирать любые элементы любой последовательности. Последовательностями в Питоне являются списки, строки, а также некоторые другие объекты, с которыми мы пока не встречались. Продемонстрируем, как выводить двумерный массив, используя это удобное свойство цикла for :
Естественно, для вывода одной строки можно воспользоваться методом join() :
Используем два вложенных цикла для подсчета суммы всех чисел в списке:
Или то же самое с циклом не по индексу, а по значениям строк:
2. Создание вложенных списков
Пусть даны два числа: количество строк n и количество столбцов m . Необходимо создать список размером n × m , заполненный нулями.
Очевидное решение оказывается неверным:
В этом легко убедиться, если присвоить элементу a[0][0] значение 5 , а потом вывести значение другого элемента a[1][0] — оно тоже будет равно 5. Дело в том, что [0] * m возвращает ccылку на список из m нулей. Но последующее повторение этого элемента создает список из n элементов, которые являются ссылкой на один и тот же список (точно так же, как выполнение операции b = a для списков не создает новый список), поэтому все строки результирующего списка на самом деле являются одной и той же строкой.
В визуализаторе обратите внимание на номер id у списков. Если у двух списков id совпадает, то это на самом деле один и тот же список в памяти.
Таким образом, двумерный список нельзя создавать при помощи операции повторения одной строки. Что же делать?
Первый способ: сначала создадим список из n элементов (для начала просто из n нулей). Затем сделаем каждый элемент списка ссылкой на другой одномерный список из m элементов:
Другой (но похожий) способ: создать пустой список, потом n раз добавить в него новый элемент, являющийся списком-строкой:
Но еще проще воспользоваться генератором: создать список из n элементов, каждый из которых будет списком, состоящих из m нулей:
В этом случае каждый элемент создается независимо от остальных (заново конструируется список [0] * m для заполнения очередного элемента списка), а не копируются ссылки на один и тот же список.
3. Ввод двумерного массива
Пусть программа получает на вход двумерный массив в виде n строк, каждая из которых содержит m чисел, разделенных пробелами. Как их считать? Например, так:
Или, без использования сложных вложенных вызовов функций:
Можно сделать то же самое и при помощи генератора:
4. Пример обработки двумерного массива
Пусть дан квадратный массив из n строк и n столбцов. Необходимо элементам, находящимся на главной диагонали, проходящей из левого верхнего угла в правый нижний (то есть тем элементам a[i][j] , для которых i==j ) присвоить значение 1 , элементам, находящимся выше главной диагонали – значение 0, элементам, находящимся ниже главной диагонали – значение 2. То есть необходимо получить такой массив (пример для n==4 ):
Рассмотрим несколько способов решения этой задачи. Элементы, которые лежат выше главной диагонали – это элементы a[i][j] , для которых i<j , а для элементов ниже главной диагонали i>j . Таким образом, мы можем сравнивать значения i и j и по ним определять значение A[i][j] . Получаем следующий алгоритм:
Данный алгоритм плох, поскольку выполняет одну или две инструкции if для обработки каждого элемента. Если мы усложним алгоритм, то мы сможем обойтись вообще без условных инструкций.
Сначала заполним главную диагональ, для чего нам понадобится один цикл:
Затем заполним значением 0 все элементы выше главной диагонали, для чего нам понадобится в каждой из строк с номером i присвоить значение элементам a[i][j] для j = i+1 , . n-1 . Здесь нам понадобятся вложенные циклы:
Аналогично присваиваем значение 2 элементам a[i][j] для j = 0 , . i-1 :
Можно также внешние циклы объединить в один и получить еще одно, более компактное решение:
А вот такое решение использует операцию повторения списков для построения очередной строки списка. i -я строка списка состоит из i чисел 2 , затем идет одно число 1 , затем идет n-i-1 число 0 :
А можно заменить цикл на генератор:
5. Вложенные генераторы двумерных массивов
Для создания двумерных массивов можно использовать вложенные генераторы, разместив генератор списка, являющегося строкой, внутри генератора всех строк. Напомним, что сделать список из n строк и m столбцов можно при помощи генератора, создающего список из n элементов, каждый элемент которого является списком из m нулей:
Но при этом внутренний список также можно создать при помощи, например, такого генератора: [0 for j in range(m)] . Вложив один генератор в другой, получим вложенные генераторы:
Но если число 0 заменить на некоторое выражение, зависящее от i (номер строки) и j (номер столбца), то можно получить список, заполненный по некоторой формуле.
Например, пусть нужно задать следующий массив (для удобства добавлены дополнительные пробелы между элементами):
В этом массиве n = 5 строк, m = 6 столбцов, и элемент в строке i и столбце j вычисляется по формуле: a[i][j] = i * j .
Pretty print 2D list?
Is there a simple, built-in way to print a 2D Python list as a 2D matrix?
would become something like
I found the pprint module, but it doesn’t seem to do what I want.
12 Answers 12
To make things interesting, let’s try with a bigger matrix:
UPD: for multiline cells, something like this should work:
And then apply the above code.
For Python 3 without any third part libs:
If you can use Pandas (Python Data Analysis Library) you can pretty-print a 2D matrix by converting it to a DataFrame object:
You can always use numpy:
Output:
Explanation *row unpacks row , so print("A", "B") is called when row is ["A", "B"] , for example.
Note Both answers will only be formatted nicely if each column has the same width. To change the delimiter, use the sep keyword. For example,
One-liner without a for loop
‘ ‘.join(row) for row in matrix) returns a string for every row, e.g. A B when row is ["A", "B"] .
*(‘ ‘.join(row) for row in matrix), sep=’\n’) unpacks the generator returning the sequence ‘A B’, ‘C D’ , so that print(‘A B’, ‘C D’, sep=’\n’) is called for the example matrix given.
Python: вывод данных в консоль
При разработке программ постоянно используется вывод данных в консоль. Например, при тестировании функций программы, которая ещё не обзавелась графическим интерфейсом, или как средство нахождения ошибок и отладки кода.
Python предоставляет программисту инструменты, позволяющие не просто выводить данные в консоль, но и форматировать их.
Функция print и её параметры
Функция print() включена в стандартную библиотеку языка Python, как основной инструмент для вывода данных в консоль или любое другое устройство (экран, принтер и так далее).
Программист может настраивать вывод данных, используя аргументы функции:
*objects
Это данные, которые выводятся на экран. Программист передает в функцию сколько угодно объектов, которые автоматически преобразуются в строковый формат и направляются в поток вывода.
Передавая объекты в функцию, программист может их передавать через запятую или использовать конкатенацию. Передача нескольких аргументов не приведёт к конфликту между *objects и другими необязательными аргументами, потому что интерпретатор автоматически распознаёт остальные параметры по ключевому слову (sep, end, file, flush)!
Вот пример:
Этот аргумент определяет, что будет стоять между переданными объектами. По умолчанию параметр sep имеет значение » «, то есть при выводе нескольких объектов, между ними будет установлен пробел, поменяем его на другой символ, например «-«:
Аргумент определяет символ, которым заканчивается выполнение функции print(). По умолчанию это символ переноса строки «\n», то есть после вывода всех данных каретка переходит на следующую строку, и следующий вывод функции print начинается с новой строки. Если нужно, чтобы вывод нескольких print был в одну строку — следует заменить последний символ.
Вот пример:
Этот аргумент позволяет переопределить поток вывода. По умолчанию установлено значение «sys.stdout», то есть данные выводятся в консоль. Если вместо этого указать какой-нибудь файл, то в данные запишутся в него.
Вот пример скрипта на Python, который откроет файл temp.txt и запишет в него текст с помощью функции print:
flush
Этот необязательный аргумент позволяет отчистить поток вывода. По умолчанию имеет значение False, когда вывод буферизуется, программист может указать значение «True», чтобы вывод производился сразу. Например, если вы пишете в файл данные, то они попадают в буфер и записываются реально в файл когда буфер заполнится или будет закрыт файл.
Аналогично и с выводом в консоль, данные записываются в буфер и выводятся из него в консоль. Если flush выставлен в True, то вывод производится немедленно.
Форматированный вывод
Для того чтобы выведенную в консоль информацию можно было без проблем прочитать и понять, она должна быть форматирована. Python предоставляет программисту инструменты, позволяющие форматировать вывод в консоль разными способами. С их помощью можно даже создать ровную и читаемую таблицу.
Оператор %
Оператор % часто используется для форматирования и хорошо известен не только программистам на Python, но и программистам на C/С++. По сути, оператор % — это метка, вместо которой подставляется значение переменной или выражение. Оператор % размещается непосредственно в выводимой строке, а подставляемые значения — в кортеже после второго %. Пример:
Помимо символа % указывается тип значения, а также, по желанию, длина и точность. Синтаксис выглядит так:
Если рассмотреть пример, можно увидеть, что:
- « %2d » используется для первого элемента кортежа, целого числа «4». Так как после % указана длина «2», а число в кортеже состоит только из одной цифры, в выводе добавится дополнительный пробел.
- « %5.2f » — это формат для чисел с плавающей точкой. «5» — это общее количество цифр, которые должна содержать строка, а «.2» — это количество цифр после запятой.
Метод format
Этот инструмент был добавлен в Python версии 2.6. В сравнении с предыдущем способом format оказывается чуть более громоздким. Программист использует символ «<>», чтобы отметить место, в которое будет подставлена переменная или выражение. Внутри фигурных скобок можно указать имя, тип значения, ширину и точность.
Подставляемые значения указываются в кортеже после ключевого слова format. Их можно указывать как позиционно, так и присваивать по имени. Пример:
Метод format также позволяет форматировать числа, то есть указывать их ширину и точность:
Этот способ позволяет очень гибко форматировать вывод данных. Например, программист может передавать в строку данные из готового словаря:
Строковый метод
Вывод с помощью строкового метода формируется с использованием операций среза и методов строк. Для работы со строковым типом данных создано несколько методов, которые позволяют просто и изящно форматировать вывод, среди них методы: ljust() , rjust() , center() .
centre()
Эта функция выравнивает строку по центру в соответствии с указанной шириной, заполняя недостающую ширину пробелами. Она имеет следующий синтаксис:
Здесь:
- str — это строка, которую будем центрировать.
- len – это ширина строки.
- fillchr — символ, которым заполняется недостающее пространство (по умолчанию — пробел).
Пример:
Если поменять символ заполнения, получится следующее:
ljust()
Метод работает аналогично centre() , только выравнивает текст не по центру, а по левому краю. То есть недостающие символы дополняются не с двух сторон, а только с правой.
rjust()
Метод работает аналогично centre() , но выравнивает текст по правому краю. То есть символы дополняются только с левой стороны.
f-строки
Иногда нужно просто вставить значение переменной в какую-то часть строки. Можно воспользоваться одним из методов форматирования, строить длинные конструкции из комбинаций строк и имён переменных, соединённых запятыми (или «+»), например:
Однако в Python версии 3.6 в язык был добавлен простой и удобный инструмент, который называется f-строка или интерполированная строка. С его помощью можно удобно вставлять переменные в любое место выводимой строки. Для этого используются фигурные скобки «<>», внутри которых указывается имя переменной, а перед строкой ставится символ «f». Пример:
Поля заданной ширины
В приведённых выше примерах уже использовались инструменты для настройки ширины полей. Ширина поля вывода настраивается с помощью вставки численного значения между знаком «%» и типом вывода (например, «d»). То есть установка ширины поля выглядит так:
Установка ширины полей работает так:
- Интерпретатор получает информацию о численном значении ширины вывода (в примере это «6»).
- Затем он получает информацию о подставляемом значение, то есть считает, из скольки символов оно состоит (в примере это «1»).
- Если количество символов в подставляемом значение меньше, чем ширина строки, при выводе в строку добавляются дополнительные пробелы, иначе значение просто выводится.
Примеры
С помощью форматированного вывода можно полностью настроить любой вывод в консоль, например:
Вывод ошибки
Ниже пример обработки ошибки. Мы перехватываем исключение в блоке except и выводим сообщение о ней с помощью функции print.
Вывод списка
Ниже пример того как выводится список в одну строку:
Если нужно перечислить элементы списка в столбик с указанием порядковых номеров, то это можно сделать следующим образом:
Вывод массива
Здесь выводим массив построчно с указанием номеров элементов.
Вывод словаря
Здесь приведём два варианта для словарей.
Простой вариант:
В виде таблицы:
Вывод матрицы
Сложность в выводе матрицы состоит в том, что из-за разных длин чисел элементы столбца будут стоять не друг под другом, а со смещением. С помощью форматирования можно решить эту проблему.
Здесь мы создали матрицу в виде двумерных списков, но если вы работаете с матрицами с помощью библиотеки NumPy, то там вывод в консоль форматируется автоматически.
Двумерные массивы в Python
Нередко в задачах приходится хранить прямоугольные таблицы с информацией. Их принято называть двумерными массивами или матрицами. В языке программирования Python программист может представить таблицу в виде списка строк, каждый элемент которого тоже выступает списком (к примеру, чисел).
Приведем пример создания числовой таблицы, состоящей из трех столбов и двух строк:
В примере первая строка списка 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.
Обычно для обработки и вывода списка применяется два вложенных цикла: по номеру строки и по элементам внутри строки.
Пример вывода двумерного числового списка на экран по строкам (числа разделены внутри одной строки с помощью пробелов):
Такой же пример, но циклы по значением списка, а не по индексу:
Пример вывода одной строки с помощью метода join:
Чтобы суммировать все числа в списке, применяем два вложенных цикла:
Такой же пример, только по значением строк:
Создание вложенных списков
Например, даны два числа: n – количество строк и m – количество столбцов. Нужно создать список размером n×m, заполнив его нулями:
Очевидное решение получилось неверным:
Чтобы убедиться в этом, достаточно присвоить значение 1 элементу A[0][0], после чего вывести значение другого элемента A[1][0], которое тоже будет 1. Все потому, что 0] * m возвращает ссылку на список из m нулей. Однако дальнейшее повторение данного элемента создает список из элементов n, которые выступают ссылкой, ведущей на один и тот же список, поэтому все строки списка являются одной и той же строкой.
Двумерный список нельзя создавать посредством операции повторений одной строки. Как найти выход? Существует несколько решений.
Первое решение: создайте список из n элементов (например, из n нулей). После чего сделайте каждый элемент списка в виде ссылки на другой одномерный список, состоявший из m элементов:
Второе решение (похожее): для начала создайте пустой список, затем n раз добавьте в него новый элемент, выступающий списком-строкой:
Однако проще всего воспользоваться генератором, а именно создать список из n элементов, каждый из которых тоже будет списком из m нулей:
В таком случае каждый элемент будет создаваться независимо от других (для заполнения очередного элемента списка заново конструируется список [0] * m, а не копируются ссылки на один и тот же список.
Ввод двумерного массива
Программа получает двумерный массив на вход представленный n строками, каждая из которых содержит m чисел, которые разделены пробелами. Сосчитать их можно следующим образом:
Есть еще один способ – не прибегать к сложных вложенных вызов функций:
A = []
for i inrange(n):
row = input().split()
for i inrange(len(row)):
row[i] = int(row[i])
A.append(row)
Также можно воспользоваться генератором:
Обработка двумерного массива
Перед вам квадратный массив, состоящий из n строк и n столбцов. Элементам на главной диагонали, проходящий от левого верхнего в правый нижний угол(тем элементамA[i][j], для которых ij) необходимо присвоить значение 1, а элементам выше главной диагонали – значение 0, элементам, что ниже главной диагонали – 2. Получиться такой массив (для n=4):
Решить такую задачу можно несколькими способами. Элементы, лежащие выше главной диагонали -[i][j], для которых i j. Так, можно сравнить значение i и j и определить значение A[i][j]. Получиться следующий алгоритм:
Этот алгоритм плохой, так как выполняет 1-2 функции if, чтобы обработать каждый элемент. Если несколько усложнить алгоритм, то можно и вовсе обойтись без условных инструкций. В первую очередь заполните главную диагональ. Здесь потребуется один цикл:
Далее заполните все элементы главной диагонали значением 0. Для этого в каждой из строй с номером i присвоить значение элементам A[i][j] для j=i+1, …, n-1. Потребуются вложенные циклы:
Точно также присваиваем элементам A[i][j] для j=0, …, i-1 значение 2:
Также можно объединить внешние циклы в один, чтобы получить более компактное решение:
for i inrange(n):
for j inrange(0, i):
A[i][j] = 2
A[i][i] = 1
for j inrange(i + 1, n):
A[i][j] = 0
Еще одно решение, которое подразумевает использование операции повторения списков с целью построения очередной строки списка . i-я строка списка состоит из i чисел 2, а после него одно число 1, затем идет n-i-1 число 0:
Цикл можно заменить на генератор:
A = [[2] * i + [1] + [0] * (n — i — 1) for i inrange(n)]
Вложенные генераторы двумерных массивов
Вложенные генераторы успешно используются для создания двумерных массивов. Разместите генератор списка, выступающий строкой, внутри генератора для строк. К примеру, сделайте список из n строк и m столбцов посредством генератора, создающего список из n элементов. При этом каждый элемент будет списком из m нулей:
Внутренний список так можно создать с помощью следующего генератора: [0 for j inrange(m)]. После того как вы вложите один генератор в другой получится вложенные генераторы:
Однако если заменить число 0 на некоторое выражение, зависящее от j (номер столбца) и i (номер строки), то получите список, заполненный по некоторой формуле.
Представьте, что нужно задать следующий массив (дополнительные пробелы между элементами были добавлены для удобства):
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
В текущем массиве m = 6 столбцов, n = 5 строк, и элемент в столбце j и строке i вычисляется по формуле: