Списки в python
Списки особенно удобны для хранения в них объектов в определенном порядке, особенно если порядок или содержимое нужно будет изменить. Список изменяем, поэтому можно добавлять новые элементы, перезаписывать существующие или удалять. Одно и то же значение в списке может встречаться много раз
Синтаксис
Как в случае других переменных, иногда нужно задать пустое значение списку (как 0 для чисел или ” для строк). Делается так:
В списке ЛУЧШЕ хранить один тип данных, а не кидать туда всё подряд по типу
[3, 'test', 0, 'asd', False]
. Так нельзя, ибо доступ к отдельным элементам списка затрудняется.
Элементы списка (a[0]
, a[1]
и a[2]
) - это, по сути, имена, указывающие, in this case, на int объекты со значениями 2, 4, 6.
.append()
и .extend()
Чтобы добавить в конец списка элемент - нужно:
Если нужно добавить несколько элементов, то есть список, то нужно воспользоваться list.extend()
, потому что list.append()
принимает только один аргумент.
Как называются такие конструкции, почему используется точка?
Конструкция типа
list.append()
называется методом. Методы - это функции, которые связаны с определенным объектом и могут быть вызваны через оператор точки.В примере
list.append()
,append()
- это метод объектаlist
, который добавляет новый элемент в конец списка. Оператор точки используется для вызова метода на конкретном объекте. В этом случае, методappend()
вызывается на объектеlist
, чтобы добавить новый элемент в список.Методы являются одним из способов организации и структурирования кода в ООП (объектно-ориентированном программировании). Они позволяют связать функциональность с определенным объектом, что упрощает и улучшает читаемость кода. Кроме того, методы позволяют изолировать и скрыть детали реализации функциональности, что делает код более модульным и поддерживаемым.
Индекс
Это номер позиции элемента в списке.
Индекс номера 5
в списке [1, 5, 45, 0]
будет равен 2, то есть, второй элемент списка.
Взаимодействовать с элементами можно, указав имя списка и в квадратных скобках индекс элемента в списке.
Здесь тоже, как и везде в программировании, отчет ведется с 0. Поэтому первый элемент списка имеет индекс 0, а не 1.
Строки
Срезы (slices)
Срезы позволяют брать нужный кусок списка.
Копии списка
Как раз чтобы избежать ошибок при копировании списков вместо:
Нужно использовать такой слайс:
Куски из списка
То есть, вместо вывода нужного куска из списка циклом:
Можно:
Также если нужно взять срез до/с какого-то индекса нужно:
Шаг в срезе:
Замена с помощью срезов:
Можно взять срез из среза (стэкать их):
Сдвиг списка
Так, чтобы сдвинуть на 3 шага список numbers
(получить [4, 5, 6, 7, 1, 2, 3] из [1, 2, 3, 4, 5, 6, 7]) - нужно сложить слайсы ([N:] + [:N]) с нужным шагом (3, в нашем случае):
Чтобы поменять результат - можно сделать шаг отрицательным и тестить.
Переворачивание списка
Чтобы перевернуть список нужно выбрать весь список (:) и после еще одного двоеточия указать шаг -1 ⇒ [::-1]
.
Без второго двоеточия получится “[:-1]
весь срез без последнего элемента”:
Метод insert
Позволяет добавлять элемент в список по указанному индексом позицию.
Для этого в скобках some_list.insert() указываются индекс и элемент, который нужно вставить:
Метод remove
Позволяет удалять первый найденный элемент в списке по его имени.
Для этого в скобках some_list.remove() указывается элемент, который нужно удалить:
Удаление нескольких элементов
В случаях, когда стоит задача удалить несколько элементов, например, числа 0 из всего списка - метод remove() не подходит потому, что он сам по себе работает не эффективно для такого рода задач. Он после поиска в списке нужного элемента и его удаления сдвигает весь список налево, чтобы заполнить пустоту.
Оператор del
del выполняет обратное присваивание (противоположную присваиванию операцию): открепляет имя от объекта и может освободить место объекта в памяти, если это имя являлось последней ссылкой на него.
Метод count()
Чтобы узнать, например, кол-во цифры 7 в списке нужно:
Функция list()
Добавление строки посимвольно в список:
Заполнить список с помощью range():
Вложенные списки
Пример вложенного списка (и его генерации для наглядности):
Чтобы получить элемент из вложенного списка нужно сначала обратиться к вложенному списку как к элементу (индексом в квадратных скобках) и рядом же поставит квадратные скобки и указать индекс нужного элемента:
List comprehensions
Еще называют генераторами списков, представлением списков, списковыми включениями. Этот механизм юзает итерирование с помощью ключевых слов for/in для генерации списков.
К слову существуют еще dict comprehensions, set comprehensions и т.д.
Синтаксис
Примеры
Простой список из range()
Простой список из range() с выражением
Структура записи генерации списков (2-й пример):
x**2
- это expression (выражение)
for x in
- member (переменная цикла)
range(10)
- iterable (итерируемое - функция, строка, список…)
Список из строки
Пример функции
Как добавить 3 input-а сразу в список
Условия (в представлении списков)
Вместо:
Нужно:
Структура фильтрации элементов:
Условие добавили в конце представления, то есть как фильтр.
if (x % 2 != 0)
- условие
Можно даже юзать else:
Структура выбора элементов:
<expression> если <условие> иначе <else_expression>
(x + 1) if <условие> else (x - 1)
Потом уже member и iterable.
Можно также записать готовое значение в expression:
Создание списка кортежей
.reverse()
Функция .reverse()
изменяет список, но не возвращает его значения:
Размножение элементов с помощью оператора +
.sort()
и sorted()
.sort()
сортирует сам список.
sorted()
возвращает отсортированную копию списка.
Reverse сортировка:
Изменение одинаковых списков при присваивании с помощью оператора =
Список b
тоже изменился, ибо он просто ссылается на тот же список объектов, что и a
.
Решение: Следующая глава
Копирование списков - .copy()
, list()
, слайсы и .deepcopy()
.copy()
, list()
, слайсы
Оригинальный список снова будет присвоен переменной а
. Создам b
с .copy()
, c
- с list()
, а d
- с помощью слайсов:
.deepcopy()
В таких ситуациях:
нужен .deepcopy()
, чтобы полностью скопировать список, иначе вложенные списки продолжат указывать на те же объекты, а не будут копией.
Короче, нужна полная “глубокая” копия:
Функция .deepcopy() работает с вложенными списками, словарями и т.п.
zip()
Функция
zip()
создает итератор, который объединяет элементы из нескольких источников данных. Работает со списками, кортежами, множествами и словарями для создания списков или кортежей, включающих все эти данные.
Часто используемый сценарий - параллельное итерирование по нескольким последовательностям:
Самый длинный список не проитерировался до конца
Из списка desserts не проитерировался последний элемент (
'pudding'
), ибо этот список самый длинный и до конца не проитерируется, пока не увеличишь другие списки до его размера.
LIFO и FIFO
Если вы используете функцию .append()
, чтобы добавить новые элементы в конец списка, и функцию .pop()
, чтобы удалить что-либо из конца того же списка, вы работаете со структурой данных, известной как очередь LIFO (last in, first out - «последним пришел, первым ушел»). Ее чаще называют стеком. Вызов .pop(0)
создает очередь FIFO (first in, first out - «первым пришел, первым ушел»). Это удобный способ собирать данные по мере их поступления и работать либо с самыми старыми (FIFO), либо с самыми новыми (LIFO).
Соус (не весь): Книга “Простой Python” ⇒ Глава 7. “Кортежи и списки”