Python
String Manipulation
Programming
Coding Tutorial
Python Functions

How do I reverse a string in Python?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Python strings are immutable sequences, so reversing a string always creates a new string. The most common and idiomatic way is slicing with [::-1], but there are several other approaches depending on your needs — including reversed(), manual loops, and recursion.

The slice [::-1] steps through the string backwards, producing a reversed copy:

python
s = "Hello, World!"
reversed_s = s[::-1]
print(reversed_s)  # "!dlroW ,olleH"

The slice syntax is [start:stop:step]. Omitting start and stop means "the entire string," and step=-1 means "go backwards."

python
# Reverse a substring (characters 2 through 7)
s = "abcdefghij"
print(s[7:1:-1])  # "hgfedc"

Method 2: reversed() + join()

The reversed() built-in returns an iterator over the string in reverse order. Use "".join() to build the result:

python
s = "Hello, World!"
reversed_s = "".join(reversed(s))
print(reversed_s)  # "!dlroW ,olleH"

This is slightly more readable than slicing for developers unfamiliar with the [::-1] idiom, but it is slower because it creates an iterator and then joins.

Method 3: Loop Accumulation

Build the reversed string character by character:

python
1s = "Hello"
2reversed_s = ""
3for char in s:
4    reversed_s = char + reversed_s  # Prepend each character
5print(reversed_s)  # "olleH"

This is O(n²) because string concatenation creates a new string each time. Use a list for better performance:

python
1s = "Hello"
2chars = []
3for char in s:
4    chars.insert(0, char)
5reversed_s = "".join(chars)

Or more efficiently with append and a final reverse:

python
chars = list(s)
chars.reverse()  # In-place reverse of the list
reversed_s = "".join(chars)

Method 4: Recursion

A recursive approach splits the string and reassembles in reverse:

python
1def reverse_string(s):
2    if len(s) <= 1:
3        return s
4    return reverse_string(s[1:]) + s[0]
5
6print(reverse_string("Hello"))  # "olleH"

This hits Python's recursion limit (~1000) for long strings and is very slow due to repeated string concatenation. It is mainly useful as an exercise.

Method 5: reduce()

A functional approach using functools.reduce:

python
1from functools import reduce
2
3s = "Hello"
4reversed_s = reduce(lambda acc, char: char + acc, s)
5print(reversed_s)  # "olleH"

Performance Comparison

python
1import timeit
2
3s = "a" * 10000
4
5# Slicing — fastest
6timeit.timeit(lambda: s[::-1], number=10000)          # ~0.02s
7
8# reversed + join — fast
9timeit.timeit(lambda: "".join(reversed(s)), number=10000)  # ~0.08s
10
11# list reverse + join
12timeit.timeit(lambda: "".join(list(s)[::-1]), number=10000)  # ~0.10s
13
14# Loop — slow
15timeit.timeit(lambda: "".join([s[i] for i in range(len(s)-1, -1, -1)]), number=10000)  # ~0.50s
MethodTime ComplexitySpeedReadability
s[::-1]O(n)FastestPythonic
"".join(reversed(s))O(n)FastClear intent
list(s).reverse() + joinO(n)FastVerbose
Loop prependO(n²)SlowSimple
RecursionO(n²)SlowestEducational

Reversing Words (Not Characters)

To reverse word order while keeping each word intact:

python
1sentence = "Hello World Python"
2
3# Reverse word order
4reversed_words = " ".join(sentence.split()[::-1])
5print(reversed_words)  # "Python World Hello"
6
7# Reverse each word individually
8reversed_each = " ".join(word[::-1] for word in sentence.split())
9print(reversed_each)  # "olleH dlroW nohtyP"

Unicode Considerations

Slicing works correctly with most Unicode, but combined characters (like accented letters using combining marks) can break:

python
1s = "café"   # If é is a single codepoint, this works
2print(s[::-1])  # "éfac"
3
4# But with combining characters (e + combining accent):
5s = "cafe\u0301"  # "café" using combining acute accent
6print(s[::-1])    # "´efac" — the accent attaches to the wrong character

For safe Unicode reversal, use the grapheme library or unicodedata normalization.

Common Pitfalls

  • Strings are immutable: All methods create a new string. You cannot reverse a string in place in Python.
  • O(n²) concatenation: Building a string with += or prepend in a loop is quadratic. Use list + join instead.
  • Recursion limit: reverse_string() via recursion fails on strings longer than ~1000 characters. Use sys.setrecursionlimit() cautiously or avoid recursion altogether.
  • Unicode combining characters: [::-1] reverses codepoints, not grapheme clusters. Combined emoji or accented characters may break.

Summary

  • Use s[::-1] for the fastest, most Pythonic string reversal
  • Use "".join(reversed(s)) for explicit readability
  • Avoid loop-based or recursive approaches in production code due to poor performance
  • To reverse word order, split first then reverse: " ".join(s.split()[::-1])
  • Be cautious with Unicode combining characters when reversing

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.