📜 Классический подход с ручными индексами
Во многих учебных материалах новичкам показывают перебор строки по индексам. Это работает, но не является Pythonic-стилем.
text = "Python"
for i in range(len(text)):
letter = text[i]
print(letter)
Что здесь происходит: мы вручную генерируем индексы от 0 до len(text) - 1, а затем по каждому индексу извлекаем символ. Это лишние действия и лишние возможности для ошибок.
❌ Почему этот подход может быть не лучшим сейчас
- Лишние индексы: если вам нужны сами элементы, индексы избыточны и отвлекают.
- Ошибки off-by-one: ручной подсчёт границ
range(len(...))легко сломать. Менее читаемо:код читается как «для каждого индекса…», а не «для каждой буквы…».- Конкатенация строк:
"Value: " + str(i)медленнее и многословнее f-string.
✅ Рекомендуемый современный вариант
1. Прямая итерация по строке
text = "Python"
for letter in text:
print(letter)
Что улучшилось: код говорит сам за себя — «для каждой буквы в тексте».
2. enumerate() для индексов
Когда индекс всё-таки нужен, используйте enumerate() вместо range(len(...)).
text = "Python"
for index, letter in enumerate(text):
print(f"{index}: {letter}")
3. zip() для параллельного перебора
names = ["Anna", "Bob", "Charlie"]
ages = [25, 30, 35]
for name, age in zip(names, ages):
print(f"{name} is {age} years old")
4. f-strings вместо конкатенации
# Classic
print("Letter: " + letter + ", index: " + str(index))
# Modern
print(f"Letter: {letter}, index: {index}")
- Меньше индексов — меньше off-by-one ошибок.
- Код читается как описание задачи, а не как управление счётчиком.
enumerate()иzip()работают с любыми итерируемыми объектами.- f-strings быстрее и нагляднее конкатенации.
🕰️ Когда индексы всё ещё нужны
Прямая итерация предпочтительна, но индексы уместны, когда:
- Нужно изменить элементы изменяемой последовательности по позиции.
- Алгоритм явно оперирует позициями, а не значениями (например, сортировка).
- Работаем с несколькими последовательностями по одним и тем же индексам.
Даже в этих случаях enumerate() часто делает код чище, чем range(len(...)).
🔧 Как распознать устаревший код
В legacy-проектах можно встретить конструкции вида:
for i in range(len(data)):
item = data[i]
# ...
Если i используется только для доступа к data[i], безопасно замените на:
for item in data:
pass # replace with real logic
Если индекс тоже нужен, используйте:
for i, item in enumerate(data):
pass # replace with real logic