Разворот строк в Python: подробное руководство
Четыре способа развернуть строку в Python: срезы, reversed(), list.reverse() и рекурсия — с примерами и советами по производительности.
Разворот строки означает изменение порядка её символов так, чтобы последний символ стал первым, и так далее. Python предлагает несколько способов сделать это, каждый из которых имеет свои компромиссы в отношении читаемости, производительности и использования памяти.
В этой главе рассматриваются:
- Идиоматический однострочник с использованием нотации срезов (
[::-1]) reversed()в сочетании сjoin()- Разворот списка на месте
- Рекурсивный подход (полезен для обучения, но не для продакшена)
- Практические случаи использования: обнаружение палиндромов и разворот порядка слов
Строки в Python являются неизменяемыми — ни один из этих методов не изменяет исходную строку; все они возвращают новую.
Метод 1: Нотация срезов (рекомендуется)
Наиболее идиоматичный способ развернуть строку в Python — расширенный срез [::-1]. Трёхчастный срез [start:stop:step] по умолчанию охватывает всю строку при пропуске start и stop, а шаг -1 проходит по каждому символу в обратном направлении.
Это работает с любой последовательностью — списками, кортежами — не только со строками. Поскольку срез реализован на C внутри CPython, на практике это самый быстрый вариант.
sentence = "Python is great"
print(sentence[::-1]) # taerg si nohtyPПодробнее о синтаксисе start/stop/step см. в главе Нарезка строк.
Метод 2: reversed() и join()
Встроенная функция reversed() возвращает итератор, который перебирает символы с конца к началу. ''.join() собирает эти символы в новую строку.
Когда предпочесть этот способ срезам
reversed() более явно выражает намерение — читается как «соединить перевёрнутые символы этой строки». Некоторые команды предпочитают его при code review, поскольку он не оставляет двусмысленности относительно того, что означает пустой срез [::-1]. По производительности срезы примерно в 5 раз быстрее при типичных длинах строк, так как избегают накладных расходов итератора.
Метод 3: Цикл for
Можно итерировать строку в обратном порядке и строить новую строку символ за символом. Этот подход многословен, но делает алгоритм наглядным — полезно в учебных целях.
Замечание о конкатенации строк в цикле
Каждый += создаёт новый объект string, поскольку строки неизменяемы. Для очень длинных строк это медленно — O(n²) по времени. Если нужно строить развёрнутую строку символ за символом, собирайте символы в список и соединяйте в конце:
string = "hello world"
chars = []
for char in reversed(string):
chars.append(char)
reversed_string = ''.join(chars)
print(reversed_string) # dlrow ollehНа практике используйте срезы — но понимание версии с циклом помогает, когда нужно применять фильтрацию или преобразование во время разворота.
Метод 4: list.reverse()
Преобразуйте строку в список символов, вызовите метод .reverse() для изменения на месте, затем соедините обратно:
string = "hello"
chars = list(string)
chars.reverse() # mutates the list in place
reversed_string = ''.join(chars)
print(reversed_string) # olleh
print(string) # hello (original unchanged)Это занимает больше памяти, чем подход со срезами, поскольку создаётся полная копия списка, но он нагляден и легко читается. Метод .reverse() задокументирован в разделе методы строк Python.
Метод 5: Рекурсия
Рекурсивная функция вызывает себя с более короткой версией строки до достижения базового случая (пустой строки):
Подводный камень: ограничение глубины рекурсии
Стандартный предел рекурсии в Python равен 1000 (sys.getrecursionlimit()). Строка длиннее ~990 символов вызовет RecursionError. Используйте этот подход только в демонстрационных целях; в продакшен-коде предпочитайте срезы или reversed().
Практические случаи использования
Проверка на палиндром
Палиндром читается одинаково в обоих направлениях. Разворот и сравнение — это простейшая проверка:
def is_palindrome(text):
cleaned = text.lower().replace(" ", "")
return cleaned == cleaned[::-1]
print(is_palindrome("racecar")) # True
print(is_palindrome("hello")) # False
print(is_palindrome("A man a plan a canal Panama")) # TrueРазворот порядка слов в предложении
Разворот всей строки отличается от разворота порядка слов. Чтобы изменить порядок слов, разбейте на список и разверните его:
sentence = "Hello World Python"
reversed_words = " ".join(sentence.split()[::-1])
print(reversed_words) # Python World HelloСм. раздел Изменение строк для получения дополнительных техник преобразования строк.
Какой метод выбрать?
| Метод | Читаемость | Скорость | Память | Когда использовать… |
|---|---|---|---|---|
[::-1] | Да | Самый быстрый | Низкая | Почти всегда — это идиома Python |
reversed() + join() | Да | Быстрый | Низкая | Когда хотите сделать намерение явным |
| Цикл for | Многословный | Медленный (O n²) | Низкая | Обучение или когда нужна фильтрация/преобразование при развороте |
list.reverse() | Да | Умеренный | Выше | Когда уже есть список и нужна мутация на месте |
| Рекурсия | Да | Медленный | Стек | Только академические / демонстрационные цели |
Для почти всего реального кода string[::-1] — правильный выбор: он лаконичен, быстр и сразу понятен любому разработчику на Python.