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.
0 comments