Урок 6. Списки
Когда значений много — отметки за четверть, список покупок, результаты измерений, — заводить переменную на каждое неудобно. Их хранят в списке: одна переменная, а в ней сколько угодно значений по порядку. Список в Python — то же, что массив в Pascal, только его размер не задают заранее: он растёт и уменьшается сам.
Создание списка
Список записывают в квадратных скобках через запятую:
marks = [8, 9, 7, 10]
names = ["Аня", "Борис", "Вика"]
empty = []
print(marks)
print(len(names))
print(len(empty))[8, 9, 7, 10]
3
0len возвращает длину списка — сколько в нём элементов. Список может хранить значения любых типов и даже вперемешку, но обычно в одном списке значения одного вида.
Индексы
У каждого элемента есть номер — индекс. Нумерация начинается с нуля: первый элемент — [0], второй — [1]. Отрицательный индекс считает с конца: [-1] — последний элемент.
names = ["Аня", "Борис", "Вика"]
print(names[0])
print(names[2])
print(names[-1])
names[1] = "Глеб"
print(names)Аня
Вика
Вика
['Аня', 'Глеб', 'Вика']Элемент можно заменить, присвоив новое значение по индексу. Если обратиться к индексу, которого нет (в списке из трёх элементов — names[3]), программа остановится с ошибкой:
IndexError: list index out of rangeДобавление и удаление
Команды, которые пишут через точку после имени списка (a.append(x)), называются методами: это функции, которые работают с этим списком.
| Запись | Что делает |
|---|---|
a.append(x) | добавляет x в конец |
a.insert(i, x) | вставляет x перед элементом с индексом i |
a.remove(x) | удаляет первый элемент, равный x |
a.pop() | удаляет последний элемент и возвращает его |
a.pop(i) | удаляет элемент с индексом i и возвращает его |
del a[i] | удаляет элемент с индексом i |
x in a | True, если x есть в списке |
items = ["хлеб", "молоко"]
items.append("сыр")
items.insert(0, "вода")
print(items)
items.remove("молоко")
last = items.pop()
print(last)
print(items)
print("хлеб" in items)['вода', 'хлеб', 'молоко', 'сыр']
сыр
['вода', 'хлеб']
Trueremove для значения, которого нет в списке, выдаёт ошибку ValueError. Если не уверены, проверьте заранее: if x in items: items.remove(x).
Перебор списка
Цикл for проходит по элементам по очереди. Если нужен и номер, и значение, помогает enumerate:
marks = [8, 9, 7]
for m in marks:
print(m, end=" ")
print()
for i, m in enumerate(marks, start=1):
print(i, "—", m)8 9 7
1 — 8
2 — 9
3 — 7start=1 — с какого числа начинать нумерацию; без него счёт идёт с 0.
Сумма, наименьшее, наибольшее, среднее
marks = [8, 9, 7, 10, 6]
print(sum(marks))
print(min(marks), max(marks))
print(sum(marks) / len(marks))40
6 10
8.0Среднее — сумма, делённая на количество. Если список может быть пустым, проверьте это до деления: на ноль делить нельзя.
Срезы
Срез — часть списка: a[начало:конец]. Как и в range, конец не входит. Пропущенное начало значит «с самого начала», пропущенный конец — «до самого конца».
nums = [10, 20, 30, 40, 50]
print(nums[1:3])
print(nums[:2])
print(nums[2:])
print(nums[::-1])[20, 30]
[10, 20]
[30, 40, 50]
[50, 40, 30, 20, 10]Третье число в срезе — шаг. [::-1] — весь список задом наперёд. Срез создаёт новый список, исходный не меняется.
Сортировка
a.sort() сортирует сам список, sorted(a) возвращает новый отсортированный список, а исходный не трогает:
nums = [5, 2, 9, 1]
print(sorted(nums))
print(nums)
nums.sort(reverse=True)
print(nums)[1, 2, 5, 9]
[5, 2, 9, 1]
[9, 5, 2, 1]reverse=True — по убыванию. Сортировка по длине, по алфавиту без учёта регистра и другие случаи — в справке Как отсортировать список.
Список с клавиатуры
Числа часто вводят в одной строке через пробел. split() разрезает строку на части, map(int, …) превращает каждую часть в число, list(…) собирает результат в список:
nums = list(map(int, input().split()))
print(nums)
print(sum(nums))3 1 4 1 5[3, 1, 4, 1, 5]
14Подробно о вводе — в справке Как ввести несколько чисел в одной строке.
Список по правилу
Список можно построить одной строкой — это называется генератор списка (list comprehension):
squares = [x * x for x in range(1, 6)]
print(squares)
evens = [x for x in range(10) if x % 2 == 0]
print(evens)[1, 4, 9, 16, 25]
[0, 2, 4, 6, 8]Читается так: «x * x для каждого x из ряда 1…5» и «x для каждого x из 0…9, если x чётное». То же самое можно сделать обычным циклом с append, но длиннее.
Ловушка: копия списка
Присваивание b = a не копирует список: обе переменные указывают на один и тот же список. Изменение через b видно и через a. Настоящую копию делает a.copy() (или срез a[:]):
a = [1, 2, 3]
b = a
b.append(4)
print(a)
c = a.copy()
c.append(5)
print(a)
print(c)[1, 2, 3, 4]
[1, 2, 3, 4]
[1, 2, 3, 4, 5]Список списков
Таблицу — например, двумерный массив из школьных задач — хранят как список строк, каждая строка — тоже список. Элемент берут двумя индексами: grid[строка][столбец]. Создавать такую таблицу нужно генератором, а не умножением:
bad = [[0] * 3] * 2
bad[0][0] = 1
print(bad)
good = [[0] * 3 for _ in range(2)]
good[0][0] = 1
print(good)[[1, 0, 0], [1, 0, 0]]
[[1, 0, 0], [0, 0, 0]][[0] * 3] * 2 повторяет одну и ту же строку дважды, поэтому изменение видно в обеих. Генератор создаёт каждую строку заново. Имя _ ставят вместо переменной, которая не нужна.
Коротко
- Список —
[a, b, c]; длина —len(a); индексы с 0,a[-1]— последний элемент. append— в конец,insert— на место,remove— по значению,pop— по индексу;x in a— проверка.sum,min,maxработают со списком чисел; среднее —sum(a) / len(a).- Срез
a[i:j]— элементы сiдоj - 1;a[::-1]— наоборот. b = a— тот же список, копия —a.copy(); таблицу создают генератором.