Вся ваша работа будет крутиться вокруг списков и их преобразований. Поэтому нужно разобраться, как их создавать, изменять, как считывать из них данные. В этой статье посмотрим на работу со списками концептуально, в будущих статьях будет практика, но до этого нужно изучить ещё инструментов. Поэтому пока — списки как концептуальный инструмент в программировании.
Списки в Питоне
Списки в Питоне могут содержать разные элементы, их можно расширять и сужать, то есть добавлять или убирать элементы. Естественно, список является итерируемым объектом, по нему можно проходиться циклами и обрабатывать содержимое.
В моей практике самые частые действия над списками следующие:
- Создание пустого списка;
- Добавление элементов в существующий список;
- Обращение к элементам по индексам;
- Вычисление длины списка.
Давайте посмотрим на некоторые действия.
Создание нового списка
Самый простой способ — дать имя переменной и приравнять её к двум квадратным скобкам или написать ключевое слово list с пустыми скобками:
new_list = [] # первый способ
new_list = list() # второй способ
В итоге получается пустой список. Дальше в него можно складывать элементы.
Если вам нужно сгенерировать числовую последовательность в виде списка, то есть специальная функция range(). Синтаксис можно записать так: range(начало последовательности, до куда последовательность, шаг). Чтобы получить объект в виде списка и работать с ним дальше, как со списком, функцию нужно записать вот так: list(range(начало, конец, шаг)).
Если записать функцию в виде range(число), то получим список от нуля до указанного числа невключительно.

Если записать в виде range(число А, число Б), то получим последовательность от числа А до числа Б невключительно. Число Б должно быть больше числа А.


Если записать в полном виде range(число А, число Б, шаг), то получим последовательность от числа А до числа Б невключительно с указанным шагом. При этом число Б может быть меньше числа А, если шаг отрицательный.


В своё время я много пользовался генераторами числовых последовательностей, пока не узнал о функции zip(), про которую рассказывал в статье о циклах. После этого последовательности стали мне особо не нужны.
Добавление элементов в списки
Есть два способа — добавление в конец и расширение списка. За это отвечают два метода.
список.append() — это добавление в конец списка. Если подадите в скобках число, то в список добавится число. Если подадите в скобках другой список, то в исходный список добавится подсписок.
список.extend() — работает немного иначе. Если подать в него другой список, то он добавит в конец исходного списка содержимое другого списка, а не сам список.
В двух примерах ниже создаю список, а потом добавляю к нему методом append() сначала число, а потом список. Обратите внимание на результат, по сути, что подали, то и добавили в конец списка.


Если же добавить список к списку с помощью метода extend(), то он возьмёт элементы из списка и добавит их в исходный. В итоге получим «гладкий» список, без вложенностей.

Однако надо понимать, что extend() не будет бесконечно проваливаться в подсписки. Он готов провалиться один раз, а вот дальше уже будет добавлять то, что нашёл на первом уровне списка.

Чаще всего вы будете работать со списками одинаковой вложенности и предсказуемой структуры, поэтому метод append() сгодится в большинстве случаев.
Обращение по индексам
Мы уже смотрели на строки и срезы по ним. Строка итерируется, поэтому к каждому символу можно обратиться по его индексу в последовательности строк. В списках это тоже работает.
Чтобы обратиться к элементу списка по индексу, мы пишем имя списка и в квадратных скобках указываем номер индекса: список[x]. В примере ниже создал список от 0 до 5 невключительно, а потом запросил третий элемент списка. У третьего элемента будет индекс 2, так как отсчёт индексов идёт от нуля.

При этом можно по индексу не только получать элементы, но и менять их, задавать новое значение. Делается это через знак равно, то есть так же, как присваиваем значение в переменную. На картинке ниже всё тот же список чисел от 0 до 4, я его продублировал в переменную original_list, чтобы потом вывести её из нода и показать первоначальный вид списка. В исходный список внёс изменение: достал элемент по второму индексу и заменял на число -100.

На выходе тут два списка, измененный и исходный. Как видите, элемент со вторым индексом заменился.
Можем проводить не только замену, но и изменение элементов, всякую арифметику:

Запись в виде number_list[2] = number_list[2] + 50
довольно громоздкая. Поэтому в Питоне, для случаев, когда проводим арифметические операции над той же переменной, в которую пишем результат, есть синтаксис с более короткой записью. Выглядит он так:
number_list[2] += 50
Вместо += может быть -=, *=. Такая запись будет брать значение переменной, проводить действие, которое указали перед знаком равенства, а потом в ту же переменную запишет новое значение.

Длина списка
Как и для длины строки, для списка существует функция len(список). В скобки подаём список и получаем длину списка — целое число, равное количеству элементов в списке.

Обратите внимание, что длина списка всегда больше на единицу, чем индекс последнего элемента в списке. Потому что количество считается с единицы, а индексы с нуля.
Это важно, если хотите сгенерировать числовую последовательность на основе длины списка. По сути — получить список индексов, чтобы обращаться к элементам.

В коде выше внутри цикла я сначала считаю длину списка, а потом на её основе создаю последовательность чисел. Длина у нас равна 5. Так как range() не берёт последнее число, то получается последовательность от 0 до 4. Это как раз индексы внутри списка.
Функция enumerate()
Индексы ещё можно получать специальной функцией — enumerate(список). Она возвращает индекс элемента и сам элемент. Мне такое надо было один или два раза, то есть нечасто, но мало ли вам пригодится.
Запись выглядит так: я взял список, создал два пустых списка для индексов и для элементов списка, а потом внутри цикла применил функцию enumerate(). При этом для цикла надо создать две переменные, в первую пойдут индексы, во вторую — элементы.
Дальше я их просто закидываю в пустые списки, которые создал до цикла.

На выход подал список индексов и элементы, которые вытащил с помощью enumerate(). Само собой, вы можете что-то делать с элементами, а по индексам обращаться в другие списки такой же длины, тупо закинуть элементы в другой список особого смысла не имеет.
Опять же, всё это нафиг не нужно, когда умеете работать с функцией zip(), долгих лет ей жизни и всяческого процветания.
Методы списков
Для работы со списками в Питоне есть специальные методы, кроме append() и extend(), о которых уже упомянул. Ранее мы обсуждали работу со строками, и там методы не меняли исходную строку, а вот при работе со списками — меняют. То есть после применения метода меняется исходный список. Поэтому можно обойтись без создания новой переменной для изменённого списка.

В целом, значительная часть работы — это циклом залезть внутрь списка, обработать элементы, получить информацию, записать информацию. Преобразования прям над самим списком в моей практике встречаются редко. Поэтому большая часть методов с картинки выше мне пригождается редко.
Попрактикуемся в будущих статьях, а на это про списки достаточно.



