Создание списков
Список — упорядоченная изменяемая коллекция:
# Пустой список (оба способа равноценны)
empty = []
another_empty = list()
# С элементами
numbers = [1, 2, 3, 4, 5]
mixed = [1, "hello", 3.14, True]
nested = [[1, 2], [3, 4]] # список списков
Индексация и срезы
Работает так же, как со строками:
nums = [10, 20, 30, 40, 50]
print(nums[0]) # 10
print(nums[-1]) # 50
print(nums[1:4]) # [20, 30, 40]
print(nums[::-1]) # [50, 40, 30, 20, 10]
# В отличие от строк, списки можно изменять
nums[0] = 100
print(nums) # [100, 20, 30, 40, 50]
Методы списков
Основные методы для работы со списками:
nums = [1, 2, 3]
nums.append(4) # [1, 2, 3, 4] — добавить в конец
nums.extend([5, 6]) # [1, 2, 3, 4, 5, 6] — расширить
nums.insert(1, 99) # [1, 99, 2, 3, 4, 5, 6] — вставить по индексу
# insert(индекс, значение)
nums.remove(3) # [1, 99, 2, 4, 5, 6] — удалить по значению
# удаляется первое найденное значение слева
print(nums.pop()) # 6 — удалить и вернуть последний
print(nums.pop(0)) # 1 — удалить и вернуть по индексу
nums.sort() # [2, 4, 5, 99] — сортировка по возрастанию
nums.reverse() # [99, 5, 4, 2] — разворот
print(nums.index(4)) # 2 — индекс элемента
print(nums.count(2)) # 1 — количество вхождений
nums.clear() # [] — удалить все элементы
Если значения нет в списке, методы .remove(x) и .index(x) вызовут ошибку ValueError:
nums.remove(10) # ValueError: list.remove(x): x not in list
Сортировку по убыванию можно задать аргументом reverse=True:
nums = [3, 1, 2]
nums.sort(reverse=True) # [3, 2, 1]
Операторы со списками
Списки можно складывать, умножать и проверять на вхождение элементов:
a = [1, 2, 3]
b = [4, 5]
print(a + b) # [1, 2, 3, 4, 5] — конкатенация
print(a * 3) # [1, 2, 3, 1, 2, 3, 1, 2, 3] — повторение
print(a) # [1, 2, 3] — исходный список не изменился
print(2 in a) # True — элемент есть в списке
print(10 in a) # False
print(10 not in a) # True — отрицание
+ и * создают новый список, не изменяя исходные.
Проверка вхождения in часто используется в условиях:
if "банан" in ["яблоко", "банан", "вишня"]:
print("В корзине есть банан")
Оператор del удаляет элемент или срез по индексу. В отличие от .pop(), он удаляет элемент, не возвращая его:
nums = [10, 20, 30, 40, 50]
del nums[1] # [10, 30, 40, 50] — удалить по индексу
del nums[1:3] # [10, 50] — удалить срез
Функции len() и sorted()
Встроенная функция len() возвращает количество элементов в списке:
nums = [10, 20, 30, 40]
print(len(nums)) # 4
print(len([])) # 0 — пустой список
len() работает с любыми коллекциями — не только со списками, но и со строками, кортежами, словарями.
sorted() возвращает новый отсортированный список, не изменяя исходный. В отличие от .sort(), который сортирует список на месте, sorted() можно применять к любому итерируемому объекту:
nums = [3, 1, 4, 1, 5]
new = sorted(nums)
print(new) # [1, 1, 3, 4, 5] — отсортированный список
print(nums) # [3, 1, 4, 1, 5] — исходный не изменился
Для списков чисел полезны встроенные функции sum(), min() и max():
scores = [5, 3, 9, 1, 7]
print(sum(scores)) # 25 — сумма всех элементов
print(min(scores)) # 1 — минимальный элемент
print(max(scores)) # 9 — максимальный элемент
Перебор списка и enumerate()
Цикл for проходит по элементам списка по порядку:
fruits = ["яблоко", "банан", "вишня"]
for fruit in fruits:
print(fruit)
# яблоко
# банан
# вишня
Чтобы одновременно получить индекс и элемент, используют enumerate() — она возвращает пары (индекс, значение). Каждая пара — это кортеж, о которых подробнее в уроке 27:
for i, fruit in enumerate(fruits):
print(i, fruit)
# 0 яблоко
# 1 банан
# 2 вишня
Счёт по умолчанию начинается с 0. Если нужно начинать с другого числа, передайте его вторым аргументом:
for i, fruit in enumerate(fruits, 1):
print(f"{i}. {fruit}")
# 1. яблоко
# 2. банан
# 3. вишня
Копии и ссылки
Присваивание b = a не создаёт копию списка — обе переменные ссылаются на один и тот же объект. Поэтому изменения через b будут видны и в a:
a = [1, 2, 3]
b = a
b.append(4)
print(a) # [1, 2, 3, 4] — изменился тот же список
Чтобы получить независимую копию, используют метод list.copy() или срез list[:]. Такая копия — поверхностная: список с простыми значениями полностью независим от оригинала, но вложенные списки в копии и оригинале остаются общими:
a = [1, 2, 3]
b = a.copy()
c = a[:]
b.append(4)
print(a) # [1, 2, 3] — оригинал не изменился
print(b) # [1, 2, 3, 4]
nested = [[1, 2], [3, 4]]
shallow = nested[:]
shallow[0].append(99)
print(nested) # [[1, 2, 99], [3, 4]] — внутренний список общий