Python String Reversal: Understanding [::-1] Slice Notation

Python String Reversal: Understanding [::-1] Slice Notation

To reverse a string in Python:

text = "hello"
reversed_text = text[::-1]
print(reversed_text)  # "olleh"

The [::-1] syntax is slice notation with a negative step. It works on any sequence—strings, lists, tuples. Understanding slicing means understanding one of Python's core features.

Basic Slicing

Slicing extracts a portion of a sequence:

s = "hello"
print(s[1:4])  # "ell"

The syntax is [start:stop]. It includes start but excludes stop:

  • s[1:4] gives indices 1, 2, 3 (not 4)

Omitting start begins at the start:

s[:3]  # "hel" (indices 0, 1, 2)

Omitting stop goes to the end:

s[2:]  # "llo" (indices 2, 3, 4)

Omitting both copies the entire sequence:

s[:]  # "hello" (all indices)

The Step Parameter

Slicing has a third parameter: step:

[start:stop:step]

The step controls how many indices to skip:

s = "hello"
print(s[::2])  # "hlo" (every second character)

Here, ::2 means start at 0, end at the end, step by 2. You get indices 0, 2, 4.

Negative Step

A negative step reverses direction:

s[::-1]  # Start at end, go to start, step backward

With step = -1, Python starts at the last element and moves backward one position at a time. This reverses the sequence.

Breaking it down:

  • start: omitted (defaults to end when step is negative)
  • stop: omitted (defaults to beginning when step is negative)
  • step: -1 (move backward)

The result is the entire sequence, reversed.

Why [::-1] Works for Reversal

Let's trace it:

s = "abc"
# Indices: 0='a', 1='b', 2='c'

s[::-1]
# Start at index 2 ('c')
# Move to index 1 ('b')
# Move to index 0 ('a')
# Result: "cba"

The negative step makes the sequence traverse backward. The omitted start and stop ensure you get everything.

Other Negative Steps

You can use negative steps other than -1:

s = "hello"
print(s[::-2])  # "olh" (every second character, reversed)

This starts at the end and steps backward by 2. You get indices 4, 2, 0, which are 'o', 'l', 'h'.

Negative Indices

Python also supports negative indices for start and stop:

s = "hello"
print(s[-1])    # 'o' (last character)
print(s[-2])    # 'l' (second-to-last)
print(s[-3:])   # "llo" (last three characters)
print(s[:-2])   # "hel" (all but last two)

Negative indices count from the end. s[-1] is the last element, s[-2] is one before that, and so on.

You can combine negative indices with reversal:

s[-3::-1]  # Start at third-from-last, go backward to start
# "hello"[-3::-1] = "leh"

Practical Uses

Palindrome check:

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

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

Reversing words while preserving order:

sentence = "hello world"
reversed_words = ' '.join(word[::-1] for word in sentence.split())
print(reversed_words)  # "olleh dlrow"

Reversing a list:

numbers = [1, 2, 3, 4, 5]
reversed_numbers = numbers[::-1]
print(reversed_numbers)  # [5, 4, 3, 2, 1]

Note: this creates a new list. For in-place reversal, use list.reverse():

numbers.reverse()  # Modifies in place

Performance Considerations

[::-1] creates a new string. Strings are immutable in Python, so you can't reverse one in place. The slice creates a copy with characters in reverse order.

For lists, slicing also creates a copy. If you want in-place reversal:

numbers.reverse()  # Faster, no copy

But for strings, [::-1] is the standard approach. There's no in-place option because strings are immutable.

Alternatives to [::-1]

There are other ways to reverse:

Using reversed():

s = "hello"
reversed_s = ''.join(reversed(s))

reversed() returns an iterator, which you join into a string. This is more explicit but less concise.

Manual loop:

s = "hello"
reversed_s = ""
for char in s:
    reversed_s = char + reversed_s

This is slow for long strings—each concatenation creates a new string object. Use slicing or reversed() instead.

Slicing Beyond Reversal

Slicing is powerful for many patterns:

Getting every nth element:

numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
evens = numbers[::2]   # [0, 2, 4, 6, 8]
odds = numbers[1::2]   # [1, 3, 5, 7, 9]

Skipping first and last:

data = [1, 2, 3, 4, 5]
middle = data[1:-1]  # [2, 3, 4]

Extracting chunks:

text = "2024-01-15"
year = text[:4]    # "2024"
month = text[5:7]  # "01"
day = text[8:]     # "15"

Common Mistakes

Confusing negative step with negative indices:

s = "hello"
s[-1]     # 'o' (last character)
s[::-1]   # "olleh" (entire string reversed)

Negative index accesses a position. Negative step reverses direction.

Forgetting stop is exclusive:

s = "hello"
s[0:3]  # "hel" (not "hell")

To include index 3, use s[0:4].

Modifying sliced strings:

s = "hello"
s[::-1] = "olleh"  # Error - can't assign to slice of string

Strings are immutable. Create a new string instead:

s = s[::-1]

Slice Objects

You can create reusable slices:

reverse_slice = slice(None, None, -1)
s = "hello"
print(s[reverse_slice])  # "olleh"

This is useful when applying the same slice to multiple sequences:

last_three = slice(-3, None)
print("hello"[last_three])   # "llo"
print([1, 2, 3, 4, 5][last_three])  # [3, 4, 5]

Further Reading

The Python tutorial's section on strings covers slicing basics.

For advanced slicing patterns, see the slice() documentation.

Stack Overflow's question on slice notation has detailed explanations with examples.

Slicing is one of Python's most useful features.

Wear the code

Product mockup

string[::-1] Developer T-Shirt (Python Edition — Dark Mode)

£25.00

View product
Product mockup

string[::-1] Developer T-Shirt (Python Edition — Light Mode)

£25.00

View product

0 comments

Leave a comment

Please note, comments need to be approved before they are published.