W3docs

Перебор списков

Как перебирать списки 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
cherry

Python присваивает каждый элемент переменной 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 += 1
10
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(). См. раздел Сортировка списков для сортировки в обратном порядке, сортировки по ключу и других возможностей.

Связанные темы

Практика

Практика
Какой из следующих вариантов правильно выводит каждый элемент списка 'items' с помощью цикла for?
Какой из следующих вариантов правильно выводит каждый элемент списка 'items' с помощью цикла for?
Was this page helpful?