Перебор списков
Как перебирать списки Python с помощью for, while, enumerate(), zip(), break, continue и списковых включений — с примерами.
Перебор списка — обход каждого элемента по очереди — одна из самых распространённых операций в Python. В этой главе рассматриваются все практические способы это сделать: циклы for, циклы while, enumerate(), zip(), break и continue, а также списковые включения. Кроме того, объясняются подводные камни, которые нужно учитывать при изменении списка во время итерации.
Зачем перебирать список?
Список Python хранит упорядоченную последовательность элементов. Циклы позволяют выполнять действия с каждым элементом, не записывая отдельную строку кода для каждого из них. Суммирование цен, фильтрация записей, преобразование строк — во всех этих задачах цикл, как правило, является нужным инструментом.
Перебор с помощью цикла for
Самый простой и читаемый способ обойти список — цикл for.
fruits = ['apple', 'banana', 'cherry']
for fruit in fruits:
print(fruit)apple
banana
cherryPython присваивает каждый элемент переменной fruit по очереди, выполняет блок с отступом и переходит к следующему элементу. Цикл завершается автоматически, когда список исчерпан — управление индексом не требуется.
Перебор с range() и индексом
Если нужны одновременно индекс и значение, можно объединить range() с len():
colors = ['red', 'green', 'blue']
for i in range(len(colors)):
print(i, colors[i])0 red
1 green
2 blueЭто работает, но enumerate() (рассмотрен далее) является более чистым решением для данного шаблона.
Перебор с enumerate()
enumerate() связывает каждый элемент с его индексом и представляет собой идиоматичный подход Python, когда нужны оба значения:
fruits = ['apple', 'banana', 'cherry']
for index, fruit in enumerate(fruits):
print(index, fruit)0 apple
1 banana
2 cherryМожно начать счётчик с другого числа, передав второй аргумент:
for index, fruit in enumerate(['apple', 'banana', 'cherry'], start=1):
print(index, fruit)1 apple
2 banana
3 cherryПеребор двух списков с zip()
zip() объединяет элементы двух (или более) списков попарно, чтобы можно было перебирать их одновременно:
names = ['Alice', 'Bob', 'Carol']
scores = [92, 85, 78]
for name, score in zip(names, scores):
print(name, '->', score)Alice -> 92
Bob -> 85
Carol -> 78Если списки имеют разную длину, zip() останавливается на более коротком. Используйте itertools.zip_longest(), если нужно продолжить до конца более длинного списка.
Перебор с помощью цикла while
Цикл while продолжает выполняться, пока условие равно True. Индексом управляете вы сами:
numbers = [10, 20, 30, 40, 50]
i = 0
while i < len(numbers):
print(numbers[i])
i += 110
20
30
40
50Циклы while полезны, когда условие остановки — не просто «конец списка», например при поиске элемента с остановкой сразу после его обнаружения.
Управление выполнением цикла
break — досрочный выход
break немедленно прерывает цикл. Это полезно, когда вы нашли искомое и дальнейший перебор не нужен:
fruits = ['apple', 'banana', 'cherry', 'date']
for fruit in fruits:
if fruit == 'cherry':
print('Found it!')
break
print(fruit)apple
banana
Found it!continue — пропуск элемента
continue переходит к следующей итерации, не выполняя оставшиеся строки текущего блока:
numbers = [1, 2, 3, 4, 5, 6]
for n in numbers:
if n % 2 == 0:
continue # skip even numbers
print(n)1
3
5Блок else в цикле
Цикл for или while может иметь блок else, который выполняется, когда цикл завершается без срабатывания break. Это удобно для шаблонов «найти и сообщить»:
target = 7
numbers = [1, 3, 5, 9]
for n in numbers:
if n == target:
print('Found', target)
break
else:
print(target, 'not in list')7 not in listПеребор среза списка
Можно итерироваться по части списка, срезав его:
items = ['a', 'b', 'c', 'd', 'e']
for item in items[1:4]: # indices 1, 2, 3
print(item)b
c
dПеребор в обратном порядке с помощью среза:
for item in items[::-1]:
print(item)e
d
c
b
aВложенные циклы
Можно вкладывать циклы for для работы со списками списков или для вычисления комбинаций:
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]
for row in matrix:
for value in row:
print(value, end=' ')
print()1 2 3
4 5 6
7 8 9 Внутренний цикл выполняет все свои итерации для каждой отдельной итерации внешнего цикла.
Списковые включения как альтернатива циклу
Списковое включение создаёт новый список, применяя выражение к каждому элементу — это компактная и читаемая альтернатива циклу for, строящему список:
numbers = [1, 2, 3, 4, 5]
# for loop approach
squares = []
for n in numbers:
squares.append(n ** 2)
# list comprehension — same result in one line
squares = [n ** 2 for n in numbers]
print(squares)[1, 4, 9, 16, 25]Можно добавить условие для фильтрации элементов одновременно:
evens = [n for n in range(1, 11) if n % 2 == 0]
print(evens)[2, 4, 6, 8, 10]Частая ошибка: изменение списка во время итерации
Не добавляйте и не удаляйте элементы из списка внутри цикла for, который перебирает этот же список. Внутренний индекс цикла основан на исходной длине, поэтому элементы могут быть пропущены или посещены дважды.
# BAD — skips items
numbers = [1, 2, 3, 4, 5]
for n in numbers:
if n % 2 == 0:
numbers.remove(n) # mutates the list mid-loop
print(numbers) # [1, 3, 5] may look correct here but...Безопасный вариант — итерироваться по копии списка или строить новый список с помощью включения:
numbers = [1, 2, 3, 4, 5]
numbers = [n for n in numbers if n % 2 != 0]
print(numbers)[1, 3, 5]Базовые операции со списками, используемые с циклами
Ниже приводится краткий обзор методов списка, которые чаще всего применяются вместе с циклами. Полный справочник см. в разделе Методы списков Python.
Добавление элементов
my_list = [1, 2, 3]
my_list.append(4)
print(my_list)[1, 2, 3, 4]Удаление элементов
remove() удаляет первое совпадающее значение и вызывает ValueError, если элемент не найден.
my_list = [1, 2, 3, 4, 5]
my_list.remove(3)
print(my_list)[1, 2, 4, 5]Сортировка списка
my_list = [3, 1, 4, 2, 5]
my_list.sort()
print(my_list)[1, 2, 3, 4, 5]sort() изменяет список на месте. Чтобы получить отсортированную копию без изменения оригинала, используйте встроенную функцию sorted(). См. раздел Сортировка списков для сортировки в обратном порядке, сортировки по ключу и других возможностей.
Связанные темы
- Списки Python — создание, индексирование и срезы списков
- Циклы for в Python — полный справочник по циклу
for - Циклы while в Python — синтаксис и шаблоны цикла
while - Списковые включения — компактное построение списка в одну строку
- Методы списков —
append,extend,pop,insertи другие - Сортировка списков — сортировка на месте и отсортированные копии
- Удаление элементов списка —
remove,pop,delиclear - Перебор словарей — итерация по парам ключ–значение
- Перебор кортежей — итерация по неизменяемым последовательностям