How-To

How-To · Strings

How to Reverse a String in Python

Reverse a Python string the idiomatic way with the slice s[::-1], or with reversed() and join() when you want the intent spelled out — and learn why there is no str.reverse() method.

XCODXHow-To · Updated

Overview

The task is simple: take a string like "hello" and produce its characters in reverse order, "olleh". You reach for it when checking palindromes, reversing digits, or undoing a sequence. Python has no dedicated reverse method for strings, but it does not need one — the recommended approach is a slice, s[::-1], which reads the whole string with a step of -1 and hands you a new reversed string in a single expression.

Which approach should you use? Default to the slice s[::-1]. It is the shortest, the fastest, and the form every Python programmer recognises at a glance. Choose the reversed() plus join() alternative only when you want the *intent* — "reverse, then rejoin" — spelled out for readers new to slicing, or when you are already working with an iterator. Both build a new string, because a Python string is immutable and can never be reversed in place. That single fact is why the task is always "produce a reversed copy," never "mutate the original."

Steps

1. Reverse with the slice s[::-1]

A slice takes s[start:stop:step]. Leave start and stop empty to cover the whole string, and set step to -1 so Python walks it from the last character to the first. The result is a new string in reverse order.

s = "hello"
reversed_s = s[::-1]
print(reversed_s)   # olleh

2. Alternative: reversed() plus join()

reversed() returns an iterator that yields the characters back to front, and "".join(...) glues them into a string. It is a little longer than the slice but names each step, which some readers find clearer. Use it when the explicitness earns its keep.

s = "hello"
reversed_s = "".join(reversed(s))
print(reversed_s)   # olleh

3. Note: there is no str.reverse()

Lists have an in-place list.reverse() method, and beginners often expect strings to have one too. They do not, and they cannot: strings are immutable, so there is nothing to reverse *in place*. Any attempt to call "hello".reverse() raises an AttributeError. The slice and the reversed() idiom are the supported ways, and both return a new string rather than changing the old one.

# Lists CAN reverse in place, which is why the confusion arises:
items = ["a", "b", "c"]
items.reverse()      # mutates the list, returns None
print(items)         # ['c', 'b', 'a']

# Strings cannot — this raises, it does not reverse anything:
"hello".reverse()    # AttributeError: 'str' object has no attribute 'reverse'

If you are curious what the slice does under the hood, you can build the reversed string by hand — start from an empty string and prepend each character. You would never write this in real code (the slice is both shorter and faster), but it makes the mechanic concrete:

# The manual equivalent of s[::-1] — for illustration only:
result = ""
for ch in "hello":
    result = ch + result   # prepend, so the last char ends up first
print(result)              # olleh

Runnable example

A complete, runnable example — wrap the slice in a small function and reverse a word end to end. Open it in the Python compiler:

def reverse(text):
    return text[::-1]

word = "hello"
print(reverse(word))          # olleh
print(reverse(word) == "olleh")  # True

The same slice powers a one-line palindrome check — a string reads the same as its reverse:

def is_palindrome(s):
    return s == s[::-1]

print(is_palindrome("racecar"))  # True
print(is_palindrome("hello"))    # False

To reverse the words of a sentence rather than its characters, split into words, reverse the list, and join back together — three steps, each of which you can see:

sentence = "the quick brown fox"
words = sentence.split()   # ['the', 'quick', 'brown', 'fox']
words.reverse()            # ['fox', 'brown', 'quick', 'the']
print(" ".join(words))     # fox brown quick the

And because the slice works on any string, you can reverse the digits of a number by turning it into a string first, then back:

n = 12345
text = str(n)[::-1]
print(text)        # '54321'
print(int(text))   # 54321 — back to an int, leading zeros dropped
# The three character-reversal forms side by side — all produce 'olleh':
s = "hello"

a = s[::-1]                 # slice — the idiomatic default
b = "".join(reversed(s))   # reversed() iterator + join
c = "".join(s[i] for i in range(len(s) - 1, -1, -1))  # explicit index walk

assert a == b == c == "olleh"  # every form agrees

Common pitfalls

One accuracy note: reversing by character is not always the same as reversing by *visual* glyph. Text with combining marks or emoji made of several code points can look wrong when reversed naively. For ordinary ASCII and simple words — the vast majority of cases — the slice s[::-1] is exactly right.

Frequently asked questions

What is the easiest way to reverse a string in Python?
Use the slice s[::-1]. It reads the whole string with a step of -1 and returns a new reversed string in one expression, e.g. "hello"[::-1] is "olleh".
Why is there no str.reverse() method in Python?
Strings are immutable, so there is nothing to reverse in place. Reversal always produces a new string, which is what s[::-1] and "".join(reversed(s)) both do.
How do I reverse a string with reversed()?
reversed(s) yields the characters back to front as an iterator; wrap it with join to get a string: "".join(reversed(s)).
Does reversing a string change the original?
No. Both the slice and the reversed()/join() approaches return a new string and leave the original untouched. Assign the result to keep it.