Многомерные списки
Часто в задачах приходится хранить прямоугольные таблицы с данными. Такие таблицы называются матрицами или двумерными массивами. В языке программирования Питон таблицу можно представить в виде списка строк, каждый элемент которого является в свою очередь списком, например, чисел. Например, создать числовую таблицу из двух строк и трех столбцов можно так:
a = [[1, 2, 3], [4, 5, 6]]
Здесь первая строка списка 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 i in range(len(a)): for j in range(len(a[i])): print(a[i][j], end=' ') print()
То же самое, но циклы не по индексу, а по значениям списка:
for row in a: for elem in row: print(elem, end=' ') print()
Естественно для вывода одной строки можно воспользоваться методом join :
for row in a: print(' '.join(map(str, row)))
Используем два вложенных цикла для подсчета суммы всех чисел в списке:
s = 0 for i in range(len(a)): for j in range(len(a[i])): s += a[i][j]
Или то же самое с циклом не по индексу, а по значениям строк:
s = 0 for row in a: for elem in row: s += elem
Создание списка
Пусть даны два числа: количество строк n и количество столбцов m . Необходимо создать список размером n × m , заполненный нулями.
Очевидное решение оказывается неверным:
a = [[0] * m] * n
В этом легко убедиться, если присвоить элементу a[0][0] значение 1 , а потом вывести значение другого элемента a[1][0] — оно тоже будет равно 1! Дело в том, что [0] * m возвращает ccылку на список из m нулей. Но последующее повторение этого элемента создает список из n элементов, которые являются ссылкой на один и тот же список (точно так же, как выполнение операции b = a для списков не создает новый список), поэтому все строки результирующего списка на самом деле являются одной и той же строкой.
Таким образом, двумерный список нельзя создавать при помощи операции повторения одной строки. Что же делать?
Первый способ: сначала создадим список из n элементов (для начала просто из n нулей). Затем сделаем каждый элемент списка ссылкой на другой одномерный список из m элементов:
a = [0] * n for i in range(n): a[i] = [0] * m
Другой (но похожий) способ: создать пустой список, потом n раз добавить в него новый элемент, являющийся списком-строкой:
a = [] for i in range(n): a.append([0] * m)
Но еще проще воспользоваться генератором: создать список из n элементов, каждый из которых будет списком, состоящих из m нулей:
a = [[0] * m for i in range(n)]
В этом случае каждый элемент создается независимо от остальных (заново конструируется список [0] * m для заполнения очередного элемента списка), а не копируются ссылки на один и тот же список.
Ввод списка
Пусть программа получает на вход двумерный массив, в виде n строк, каждая из которых содержит m чисел, разделенных пробелами. Как их считать? Например, так:
a = [] for i in range(n): a.append(list(map(int, input().split())))
Или, без использования сложных вложенных вызовов функций:
a = [] for i in range(n): row = input().split() for i in range(len(row)): row[i] = int(row[i]) a.append(row)
Можно сделать то же самое и при помощи генератора:
a = [list(map(int, input().split())) for i in range(n)]
Сложный пример обработки массива
Пусть дан квадратный массив из 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] , для которых i < j , а для элементов ниже главной диагонали i >j . Таким образом, мы можем сравнивать значения i и j и по ним определять значение a[i][j] . Получаем следующий алгоритм:
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
Данный алгоритм плох, поскольку выполняет одну или две инструкции 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
Можно также внешние циклы объединить в один и получить еще одно, более компактное решение:
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
А вот такое решение использует операцию повторения списков для построения очередной строки списка. i -я строка списка состоит из i чисел 2 , затем идет одно число 1 , затем идет n-i-1 число 0 :
for i in range(n): a[i] = [2] * i + [1] + [0] * (n - i - 1)
А можно заменить цикл на генератор:
a = [[2] * i + [1] + [0] * (n - i - 1) for i in range(n)]
Форматирование вывода
В некоторых заданиях этого листка требуется выводить элементы списка аккуратными столбцами, выравнивая числа по правому краю с фиксированной шириной столбца. Это можно сделать разными способами, один из способов: использование метода rjust .
rjust — метод объекта типа str , принимающий два параметра: длину новой строки (ширина поля вывода) и символ-заполнитель: rjust(n, ch) . Например, s.rjust(10, ‘.’) . Метод возвращает новую строку, длина которой равна n символов, исходная строка находится в конце результата (то есть исходная строка “выравнивается” по правому краю), лишние позиции заполняются символом ch. Если опустить ch, то в качестве символа-заполнителя используется пробел. Если длина исходной строки была больше n, то возвращается исходная строка без изменений (строка не обрезается).
Аналогично есть методы ljust , выравнивающий строку по левому краю и center , выравнивающий строку по центру результата.
3 варианта, как сконвертировать список(list) в строку в Python 3
Это метод строк — он берет список и соединяет элементы списка в строку.
1. Если у вас список строк, можно просто использовать join.
my_list = ["Pythonist.ru", "-", "хороший", "сайт", "по","Python"] print(" ".join(my_list)) >>>Pythonist.ru - хороший сайт по Python
2. Если это список чисел, вы можете использовать map() для приведения всех элементов списка к строке, а потом просто склеить их в одну строку методом join()
my_list2 = [66, 77, 88, 99] print(" ".join(map(str, my_list2))) >>> 66 77 88 99
3. Если вы хотите получить разделенные запятой строки, можно использовать такой shortcut кода:
my_list3 = [11, 22, 33, 44, 55] print(str(my_list3).strip('[]')) >>> 11, 22, 33, 44, 55
Больше 50 задач по Python c решением и дискуссией между подписчиками можно посмотреть тут
Как вывести list в строку python
Для вывода значений списка в строку, можно использовать распаковку:
names = ['John', 'Marry', 'Tom'] print(*names) # => John Marry Tom
При использовании этого способа тип элементов, которые содержит список, значения не имеет. В строку будет выведено всё содержимое списка:
nums = [1, 2, 3, 4] print(*nums) # => 1 2 3 4 l = [(1, 'tupple'), 'key':'value'>, True, 'str'] print(*l) # => (1, 'tupple') True str
Списки в Python: полное руководство для начинающих
Представьте, что вы собираетесь заехать за покупками в ближайший супермаркет. Что нужно сделать вначале? Верно! Составить список покупок. А в Python есть структура данных, очень напоминающая такие списки. Собственно, она так и называется — список (англ. list), — пишет сайт pythonist.ru.

Это статья о списках в Python, предназначенная для начинающих. В следующие несколько минут мы познакомимся со списками и рассмотрим самые распространенные операции с ними: срезы и модификации при помощи методов списков.
Итак, давайте погрузимся в тему списков в Python, продолжая проводить аналогии со списками покупок.
Как работают списки
Составляя список покупок, мы записываем нужные нам товары в столбик. В таком виде список легко узнаваем именно как список покупок.
Чтобы Python понял, что имеет дело со списком, нужно заключить все элементы в квадратные скобки ( [] ). Сами элементы при этом разделяются запятыми.
Вот пример создания списка из 6 элементов (пускай это будут товары, которые мы хотим купить).
shopping_list = ['apples','pens','oatmeal cookies','notepad','brushes','paint']
Изменяемость списков в Python
Имея дело со списком покупок, мы свободно можем его изменять. Например, вычеркнуть овсяное печенье и добавить любимые конфеты. Точно так же можно изменять и списки в Python. Таким образом, списки — изменяемый тип данных.
Вот как можно заменить oatmeal cookies на candy :
shopping_list[2] = 'candy' print(shopping_list) # Вывод >> ['apples', 'pens', 'candy', 'notepad', 'brushes', 'paint']
Индексация списков в Python
Вы заметили, что элемент oatmeal cookies идет в списке третьим, но чтобы его заменить, мы использовали индекс 2 ? Дело в том, что индексация начинается с нуля. В Python индекс — это по сути отступ от начала списка.
Первый элемент имеет индекс 0 (нет никакого отступа, элемент в самом начале списка). Второй элемент имеет индекс 1 . И так далее. В общем, если в списке n элементов, последний из них будет иметь индекс (n-1) .
Попытавшись обратиться к элементу по несуществующему индексу, мы получим ошибку — IndexError.
В нашем примере у нас есть список покупок из 6 элементов (диапазон индексов 0-5). Как показано в коде ниже, если мы попытаемся обратиться к элементу под индексом 6, мы получим ошибку, потому что элемента с таким индексом просто нет.
print(shopping_list[6]) # Вывод >> -------------------------------------------------------------------------- IndexError Traceback (most recent call last) in () ----> 1 shopping_list[6] IndexError: list index out of range
С другой стороны, мы можем использовать отрицательные индексы. Последний элемент списка имеет индекс -1 , предпоследний — -2 и так далее.
print(shopping_list[-1]) # Вывод >> paint
Так же, как список покупок может содержать любые товары (фрукты, овощи, сладости и т. п.), список в Python может содержать элементы любого типа.
Таким образом, список вполне может содержать в себе другие списки в качестве элементов. Это называется вложенностью, а подобные списки — вложенными.
Вот пример вложенного списка покупок, содержащего два списка поменьше:
my_nested_list = [['apple','banana'],['paint','brushes']]
Как перебирать список в цикле
Чтобы проверить, все ли мы купили, мы постоянно перечитываем список покупок. В программировании это называется «перебирать список». В Python списки перебираются в циклах, с использованием оператора in .
for item in shopping_list: print(item) # Вывод apples pens candy notepad brushes paint
Если бы нам нужно было не вывести элементы списка, а что-нибудь сделать с каждым из них, лучше было бы использовать range — чтобы получить индексы, а затем перебрать их в цикле.
Как делать срезы списков в Python
Что, если нам интересна лишь определенная часть нашего списка shopping_list ? Тогда нам стоит взять его срез, чтобы получить нужную часть элементов.
Общий шаблон срезов таков:
list_name[START:STOP:STEP]
Срез берется от индекса START (включительно) и до индекса STOP (не включая его), с шагом STEP. Каждый из параметров START, STOP, STEP может быть опущен.
- Если нам нужно, чтобы в срез попал и последний элемент, индекс STOP нужно увеличить на единицу. Например, если у нас есть список list_name = [‘apples’, ‘pens’, ‘candy’, ‘notepad’, ‘brushes’, ‘paint’] и нам нужен срез с элементами ‘notepad’ , ‘brushes’ и ‘paint’ (индексы 3, 4, 5), срез будет выглядеть как list_name[3:6] .
- Индекс START по умолчанию — 0, а индекс STOP — индекс последнего элемента списка.
- Если не указать START, срез начнется с первого элемента списка (под индексом 0).
- Если не указать STOP, в срез попадут элементы от START до самого конца списка, включая последний элемент.
- Ну а если не указать ни начальный, ни конечный индекс, срез вернет весь список целиком.
Давайте посмотрим на это в коде:
print(shopping_list[2:]) # Вывод >> ['candy', 'notepad', 'brushes', 'paint'] print(shopping_list[:2]) # Вывод >> ['apples', 'pens'] print(shopping_list[:]) # Вывод >> ['apples', 'pens', 'candy', 'notepad', 'brushes', 'paint']
Операции со списками в Python
К спискам можно применить встроенные функции Python, такие как len() , min() и max() , чтобы получить длину списка, наименьший и наибольший элементы соответственно.
Поскольку наш shopping_list содержит только строки, min() возвращает строку, которая шла бы первой, если бы список был упорядочен в алфавитном порядке. max() возвращает строку, которая шла бы последней.
Посмотрим на это в коде:
print(len(shopping_list)) >> 6 print(max(shopping_list)) >> pens print(min(shopping_list)) >> apples
Мы можем создавать новые списки, объединяя уже существующие — так же, как можем объединять списки покупок.
list_2 = shopping_list + ['noodles','almonds'] print(list_2) >> ['apples', 'pens', 'candy', 'notepad', 'brushes', 'paint', 'noodles', 'almonds']
Методы списков в Python
Помимо уже названных встроенных функций Python имеет еще и несколько специальных методов для работы со списками. С помощью этих методов можно осуществлять разные полезные операции.
Давайте подумаем о списках покупок. Какие операции мы с ними проделываем чаще всего?
- Добавляем элементы (по одному или несколько сразу)
- Удаляем элементы
- Меняем порядок элементов.
Как добавлять элементы в список
Мы можем добавлять элементы, вставляя их по одному в конец списка. Это делается при помощи метода append() . Давайте добавим grapes в наш shopping_list .
shopping_list.append('grapes') print(shopping_list) >> ['apples', 'pens', 'candy', 'notepad', 'brushes', 'paint', 'grapes']
Что, если бы мы захотели добавить в список элементы из другого списка (или другого итерируемого объекта)? Вместо того чтобы добавлять их по одному, мы можем воспользоваться методом extend() и добавить все элементы одного объекта в другой.
shopping_list.extend(['protein bars','cheese']) print(shopping_list) >> ['apples', 'pens', 'candy', 'notepad', 'brushes', 'paint', 'grapes', 'protein bars', 'cheese'
Примечание. Есть существенная разница между методами append() и extend() и оператором конкатенации + .
Оператор + создает новый список, комбинируя списки, указанные в качестве операндов. А методы append() и extend() изменяют список, для которого они вызваны, и не возвращают новых списков.
Как удалять элементы из списка
Мы можем удалять элементы из списка по одному или даже группами.
Метод pop() возвращает последний элемент списка и удаляет его, как показано ниже. Последним элементом в списке был cheese , а после применения метода pop() его не стало.
last_element = shopping_list.pop() print(shopping_list) print(last_element) # Вывод >> ['apples', 'pens', 'candy', 'notepad', 'brushes', 'paint', 'grapes', 'protein bars'] >> cheese
Если бы мы хотели удалить элемент под определенным индексом, этот индекс можно было бы передать в метод pop() в качестве аргумента.
not_needed = shopping_list.pop(2) print(not_needed) # Вывод >> candy
Если нам не нужен доступ к значению удаляемого элемента, можно воспользоваться функцией del .
При этом можно указать как индекс элемента, который нужно удалить, так и срез — чтобы удалить все элементы в указанном диапазоне.
del shopping_list[1] print(shopping_list) # Вывод >> ['apples', 'notepad', 'brushes', 'paint', 'grapes', 'protein bars']
Предположим, мы знаем, какой именно товар в списке покупок мы передумали покупать, но не знаем, какой у него индекс. В подобных случаях можно воспользоваться методом remove() и удалить элемент по значению.
В нашем примере элемент под индексом 1 — это pens . Если бы мы не знали индекс pens , мы могли бы просто написать shopping_list.remove(‘pens’) и получить такой же результат, как в примере кода выше.
Для удаления всех элементов из списка можно использовать list_name.clear() .
Примечание. При попытке удалить элемент, которого нет в списке, мы получим ValueError.
Сортировка списков в Python
Мы можем отсортировать shopping_list , вызвав метод sort() . Поскольку в нашем списке содержатся только строки, sort() отсортирует элементы по алфавиту. Если бы у нас был список чисел, по умолчанию элементы расположились бы в порядке возрастания.
При желании можно отсортировать список в порядке убывания, для этого нужно добавить опциональный аргумент reverse = True .
Примечание. Вызов метода sort() изменяет существующий список и не создает нового. Если вы хотите получить новый список с отсортированными элементами, а старый оставить в исходном состоянии, используйте метод sorted() .
shopping_list.sort() print(shopping_list) # Вывод >> ['apples', 'brushes', 'grapes', 'notepad', 'paint', 'protein bars']
Еще один полезный метод — count . С его помощью можно узнать, сколько раз определенный элемент встречается в списке. list_name.count(elt) вернет количество вхождений elt в список list_name .
Итоги
Из этой статьи вы узнали, как создавать списки, как брать срезы, как добавлять и удалять элементы из списков, а также — как сортировать списки.