← Назад к вопросам

Какой цикл использовать для перебора коллекции?

1.3 Junior🔥 41 комментариев
#Python Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Циклы для перебора коллекций в Python

Выбор правильного цикла зависит от задачи, типа коллекции и требуемого функционала. Рассмотрю все варианты.

1. for...in - Базовый цикл (Pythonic)

Описание: Самый простой и читаемый способ для большинства случаев.

# Базовый перебор списка
users = ['Alice', 'Bob', 'Charlie']
for user in users:
    print(user)

# Перебор слов
text = "Hello World"
for char in text:
    print(char)

# Перебор словаря (только ключи)
data = {'name': 'John', 'age': 30, 'city': 'NYC'}
for key in data:
    print(key)

# Перебор пар ключ-значение
for key, value in data.items():
    print(f"{key}: {value}")

# Перебор значений
for value in data.values():
    print(value)

# Перебор множества
tags = {'python', 'javascript', 'rust'}
for tag in tags:
    print(tag)

# Перебор кортежа
point = (10, 20, 30)
for coord in point:
    print(coord)

# Распаковка значений
pairs = [(1, 'a'), (2, 'b'), (3, 'c')]
for number, letter in pairs:
    print(f"{number}: {letter}")

Плюсы:

  • Просто и читаемо
  • Pythonic подход
  • Работает с любыми итерируемыми объектами

Минусы:

  • Нет доступа к индексу (нужно использовать enumerate)
  • Нет контроля над шагом итерации

2. range() - Для численных интервалов

Описание: Используй для итерации по числам, когда нужен индекс.

# Базовый range
for i in range(5):  # 0, 1, 2, 3, 4
    print(i)

# С начальной позицией
for i in range(2, 8):  # 2, 3, 4, 5, 6, 7
    print(i)

# С шагом
for i in range(0, 10, 2):  # 0, 2, 4, 6, 8
    print(i)

# В обратном порядке
for i in range(10, 0, -1):  # 10, 9, 8, ..., 1
    print(i)

# Использование с списком для доступа к индексу
users = ['Alice', 'Bob', 'Charlie']
for i in range(len(users)):
    print(f"{i}: {users[i]}")

# Перебор только четных индексов
for i in range(0, len(users), 2):
    print(users[i])

Когда использовать:

  • Когда нужны числовые последовательности
  • Когда нужен контроль над шагом
  • Когда нужны индексы (но better use enumerate!)

3. enumerate() - Для индекса и значения

Описание: Наиболее pythonic способ получить индекс и значение одновременно.

users = ['Alice', 'Bob', 'Charlie']

# Базовый enumerate
for index, user in enumerate(users):
    print(f"{index}: {user}")  # 0: Alice, 1: Bob, 2: Charlie

# С пользовательским стартовым значением индекса
for index, user in enumerate(users, start=1):
    print(f"{index}: {user}")  # 1: Alice, 2: Bob, 3: Charlie

# Для словаря
data = {'name': 'John', 'age': 30, 'city': 'NYC'}
for index, (key, value) in enumerate(data.items()):
    print(f"{index}: {key} = {value}")

# Перебор с условием
for index, user in enumerate(users):
    if index % 2 == 0:
        print(f"Even index: {user}")

Плюсы:

  • Pythonic способ
  • Читаемо
  • Можно начать с любого числа

Минусы:

  • Небольшой overhead (создает дополнительные объекты)

Когда использовать: Почти всегда когда нужен индекс

4. zip() - Для нескольких итерируемых объектов

Описание: Объединяет несколько коллекций и перебирает их параллельно.

names = ['Alice', 'Bob', 'Charlie']
ages = [30, 25, 35]
cities = ['NYC', 'LA', 'Chicago']

# Базовый zip
for name, age in zip(names, ages):
    print(f"{name} is {age} years old")

# Три коллекции
for name, age, city in zip(names, ages, cities):
    print(f"{name}, {age}, lives in {city}")

# С enumerate
for index, (name, age) in enumerate(zip(names, ages)):
    print(f"{index}: {name}, {age}")

# Разной длины коллекции
list1 = [1, 2, 3, 4, 5]
list2 = ['a', 'b', 'c']  # Короче

for num, letter in zip(list1, list2):  # Остановится на самой короткой
    print(f"{num}: {letter}")  # 1: a, 2: b, 3: c

# С fillvalue (заполнить короткую)
from itertools import zip_longest

for num, letter in zip_longest(list1, list2, fillvalue='?'):
    print(f"{num}: {letter}")  # 1: a, 2: b, 3: c, 4: ?, 5: ?

# Распаковка (обратная операция)
data = [(1, 'a'), (2, 'b'), (3, 'c')]
numbers, letters = zip(*data)
print(numbers)  # (1, 2, 3)
print(letters)  # ('a', 'b', 'c')

Когда использовать: Когда нужно перебирать несколько коллекций одновременно

5. while - Для условных циклов

Описание: Используй когда условие более сложное чем простой перебор.

# Простой while
count = 0
while count < 5:
    print(count)
    count += 1

# С условием
users = [1, 2, 3, 4, 5]
index = 0
while index < len(users) and users[index] < 4:
    print(users[index])
    index += 1

# Бесконечный цикл с break
while True:
    user_input = input("Enter command (q to quit): ")
    if user_input.lower() == 'q':
        break
    print(f"You entered: {user_input}")

# Try-except в цикле
queue = [1, 2, 3]
while True:
    try:
        item = queue.pop(0)
        print(item)
    except IndexError:
        break

Плюсы:

  • Полный контроль над логикой
  • Для условных итераций

Минусы:

  • Менее pythonic
  • Можно написать бесконечный цикл

6. List comprehension - Для трансформации коллекций

Описание: Не цикл в строгом смысле, но используется для перебора и трансформации.

users = [1, 2, 3, 4, 5]

# Основное
squared = [x**2 for x in users]
print(squared)  # [1, 4, 9, 16, 25]

# С условием
evens = [x for x in users if x % 2 == 0]
print(evens)  # [2, 4]

# Трансформация со сложной логикой
result = [f"User {x}" for x in users if x > 2]
print(result)  # ['User 3', 'User 4', 'User 5']

# Вложенные list comprehensions
matrix = [[1, 2], [3, 4], [5, 6]]
flattened = [item for row in matrix for item in row]
print(flattened)  # [1, 2, 3, 4, 5, 6]

# Dict comprehension
data = {'a': 1, 'b': 2, 'c': 3}
uppercase = {k.upper(): v for k, v in data.items()}
print(uppercase)  # {'A': 1, 'B': 2, 'C': 3}

# Set comprehension
numbers = [1, 1, 2, 2, 3, 3, 4]
unique_squared = {x**2 for x in numbers}
print(unique_squared)  # {1, 4, 9, 16}

Когда использовать: Когда нужно создать новую коллекцию на основе существующей

7. map(), filter(), reduce() - Функциональный подход

Описание: Функциональное программирование для перебора и трансформации.

users = [1, 2, 3, 4, 5]

# map - применить функцию ко всем элементам
squared = list(map(lambda x: x**2, users))
print(squared)  # [1, 4, 9, 16, 25]

# filter - оставить элементы по условию
evens = list(filter(lambda x: x % 2 == 0, users))
print(evens)  # [2, 4]

# reduce - агрегировать в одно значение
from functools import reduce
product = reduce(lambda x, y: x * y, users)
print(product)  # 120 (1*2*3*4*5)

# С named функциями
def square(x):
    return x ** 2

def is_even(x):
    return x % 2 == 0

squared = list(map(square, users))
evens = list(filter(is_even, users))

Плюсы:

  • Функциональный стиль
  • Краткий код

Минусы:

  • Менее читаемо чем list comprehension
  • Нужно оборачивать в list()

Совет: Используй list comprehension вместо map/filter

8. itertools - Продвинутые итерации

Описание: Мощные функции для сложных итераций.

from itertools import (
    islice,      # Срез итератора
    cycle,       # Циклический перебор
    repeat,      # Повторение элемента
    combinations,# Сочетания
    permutations,# Перестановки
    chain,       # Объединение итераторов
    groupby      # Группировка
)

# islice - первые N элементов
users = [1, 2, 3, 4, 5]
first_three = list(islice(users, 3))
print(first_three)  # [1, 2, 3]

# cycle - бесконечное повторение
colors = ['red', 'green', 'blue']
for i, color in enumerate(islice(cycle(colors), 7)):
    print(f"{i}: {color}")  # red, green, blue, red, green, blue, red

# repeat - повторить элемент
for val in islice(repeat(42), 3):
    print(val)  # 42, 42, 42

# combinations - сочетания
for combo in combinations([1, 2, 3], 2):
    print(combo)  # (1,2), (1,3), (2,3)

# permutations - перестановки
for perm in permutations([1, 2, 3], 2):
    print(perm)  # (1,2), (1,3), (2,1), ...

# chain - объединение
iter1 = [1, 2, 3]
iter2 = ['a', 'b', 'c']
for item in chain(iter1, iter2):
    print(item)  # 1, 2, 3, a, b, c

# groupby - группировка
data = [1, 1, 2, 2, 3, 1, 1]
for key, group in groupby(data):
    print(f"{key}: {list(group)}")
    # 1: [1, 1]
    # 2: [2, 2]
    # 3: [3]
    # 1: [1, 1]

Сравнительная таблица циклов

ЦиклПрименениеЧитаемостьПроизводительность
for...inОсновной переборОтличнаяХорошая
enumerate()С индексомОтличнаяХорошая
range()Числовые последовательностиХорошаяОтличная
zip()Несколько коллекцийХорошаяХорошая
whileУсловные циклыСредняяХорошая
List compТрансформацияОтличнаяОтличная
map/filterФункциональныйСредняяХорошая
itertoolsСложные итерацииСредняяОтличная

Мои рекомендации

class LoopingBestPractices:
    
    # 1. Используй for...in для базового перебора
    def rule_1(self):
        for item in items:
            process(item)
    
    # 2. Используй enumerate() если нужен индекс
    def rule_2(self):
        for index, item in enumerate(items):
            print(f"{index}: {item}")
    
    # 3. Используй list comprehension для трансформации
    def rule_3(self):
        squared = [x**2 for x in numbers]
        # Не используй: list(map(lambda x: x**2, numbers))
    
    # 4. Используй zip() для нескольких коллекций
    def rule_4(self):
        for name, age in zip(names, ages):
            print(f"{name}: {age}")
    
    # 5. Избегай while если можно for
    def rule_5(self):
        # ❌ Плохо
        i = 0
        while i < len(items):
            print(items[i])
            i += 1
        
        # ✓ Хорошо
        for item in items:
            print(item)
    
    # 6. Используй itertools для сложных случаев
    def rule_6(self):
        from itertools import islice
        for item in islice(items, 0, 10, 2):
            print(item)

print("Используй правильный цикл для задачи!")

Итоговая рекомендация:

  1. 99% случаев: for item in collection или for index, item in enumerate(collection)
  2. Трансформация: List comprehension
  3. Несколько коллекций: zip()
  4. Числовые последовательности: range()
  5. Условные циклы: while
  6. Сложные случаи: itertools
Какой цикл использовать для перебора коллекции? | PrepBro