Глава 11 · Очень много информации!

Ещё больше интересного со списками!

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

Ещё несколько приёмов, которые часто пригождаются при работе со списками.

len(), min(), max(), sum()

vstroennye_funkcii.py
chisla = [4, 8, 15, 16, 23, 42]
print(len(chisla))   # 6 — количество элементов
print(min(chisla))   # 4
print(max(chisla))   # 42
print(sum(chisla))   # 108

Списки списков (вложенные списки) — матрица

Элементом списка может быть другой список — так получаются таблицы (матрицы):

vlozhennye_spiski.py
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(matrix[0])      # [1, 2, 3] — первая строка
print(matrix[0][1])   # 2 — второй элемент первой строки
print(matrix[1][2])   # 6 — строка 1, столбец 2
столбец 0
столбец 1
столбец 2
строка 0
1
2
3
строка 1
4
5
6
строка 2
7
8
9
matrix[1][2] → 6 — сначала строка, потом столбец
perebor_matricy.py
for row in matrix:
    for value in row:
        print(value, end=' ')
    print()
Вложенный список + вложенный цикл — прямой перенос из главы 10
Внешний цикл идёт по строкам, внутренний — по значениям внутри строки. Это ровно тот же паттерн вложенных циклов, что и таблица умножения в главе 10, только теперь данные уже готовы в виде матрицы, а не вычисляются на лету.

Ловушка: [[0] * 3] * 3

Хочется создать сетку 3×3 из нулей одной строкой — но это частая и коварная ошибка:

lovushka_umnozheniya.py
grid = [[0] * 3] * 3
grid[0][0] = 1
print(grid)   # [[1, 0, 0], [1, 0, 0], [1, 0, 0]] — изменились ВСЕ строки!
grid[0]grid[1]grid[2][0, 0, 0]
[[0]*3]*3 создаёт ОДИН внутренний список и трижды копирует на него ссылку
*3 повторяет ссылку, а не создаёт три независимых списка
[значение] * n для неизменяемых значений (чисел, строк) работает безопасно. Но когда значение само является списком, * n просто копирует ссылку на один и тот же внутренний список n раз — ровно тот же принцип aliasing из §11.9. Правильный способ создать три НЕЗАВИСИМЫЕ строки — через comprehension:
pravilnaya_setka.py
grid = [[0] * 3 for _ in range(3)]
grid[0][0] = 1
print(grid)   # [[1, 0, 0], [0, 0, 0], [0, 0, 0]] — только первая строка

Перебор списка циклом for

perebor_spiska_v4.py
fruits = ["яблоко", "банан", "вишня"]
for fruit in fruits:
    print(fruit)
Построение списка: цикл с append() → генератор списков
Классический подход
kvadraty = []
for n in range(1, 6):
    kvadraty.append(n ** 2)
print(kvadraty)
Современный Python (list comprehension)
kvadraty = [n ** 2 for n in range(1, 6)]
print(kvadraty)
Что использовать сегодня: list comprehension (генератор списков) для простых случаев — он существует в Python с версии 2.0, так что это не вопрос новизны, а вопрос стиля: короче и, при некоторой практике, читается как одно предложение («квадрат n для каждого n из диапазона»). Для более сложной логики (с несколькими условиями или побочными эффектами) цикл с append() часто остаётся понятнее — это не всегда "хуже", выбирайте то, что легче прочитать. Подробный разбор comprehensions — в §11.20.
Практика: len/min/max/sum, вложенные списки, list comprehension
Интерактивный ноутбук прямо в браузере — Python 3.14 через Pyodide, без установки
Открыть практику →