How to Slice a String in Python

What you’ll build or solve

You’ll take any Python string and extract the exact part you need using slicing.

When this approach works best

String slicing works well when you:

  • Extract parts of structured text, like grabbing the year from "2026-02-17".
  • Format values, like removing a file extension or keeping the last 4 digits of an ID.
  • Parse fixed-position data, like reading "USR0007EU" where segments sit in known locations.

Avoid slicing when the text format can change a lot, like free-form addresses or sentences where separators vary. In those cases, use split(), partition(), or a parser.

Prerequisites

  • Python installed
  • You know what a string is

Step-by-step instructions

1) Slice with start and end indexes

Use s[start:end] to get a substring. The start index is included. The end index is excluded.

s="canada"
part=s[0:4]
print(part)

Omit start to slice from the beginning

s="canada"
part=s[:4]
print(part)

Omit end to slice to the end

s="canada"
part=s[4:]
print(part)

What to look for: if end goes past the string length, Python stops at the end instead of raising an error.

s="canada"
print(s[:999])# safe

2) Use negative indexes for the end of the string

Negative indexes count from the end. -1 is the last character.

s="INV-2026-000981"
last_four=s[-4:]
print(last_four)

Remove a known suffix

filename="report_final.pdf"
base=filename[:-4]
print(base)

Drop the first character

s="#hashtag"
clean=s[1:]
print(clean)

What to look for: s[-0:] is the same as s[0:]. Use -1, -2, and so on for “from the end.”


3) Add a step to skip characters or reverse a string

Use s[start:end:step].

code="A1B2C3D4"
every_second=code[::2]
print(every_second)

Reverse a string

s="drawer"
reversed_s=s[::-1]
print(reversed_s)

Slice backwards with a range

s="abcdefgh"
part=s[6:2:-1]
print(part)

What to look for: with a negative step, start should be greater than end for the slice to include characters.


4) Handle indexes that might go out of bounds

Slicing stays safe even when indexes fall outside the string.

s="EU-42"
print(s[:100])# safe
print(s[-100:])# safe

What to look for: out-of-range indexes do not raise IndexError in slicing, but direct indexing like s[100] does.


Examples you can copy

Example 1: Get a file extension and base name

filename="photo.png"

dot=filename.rfind(".")
base=filename[:dot]
ext=filename[dot+1:]

print(base,ext)

Example 2: Extract date parts from ISO text

date_str="2026-02-17"

year=date_str[:4]
month=date_str[5:7]
day=date_str[8:10]

print(year,month,day)

Example 3: Mask a secret but keep the last 4 characters

token="sk_live_91f3a12b700d188aa"
masked="*"* (len(token)-4)+token[-4:]
print(masked)

Example 4: Take the middle section between two markers

s="START:alpha-beta:END"

start=len("START:")
end=-len(":END")

middle=s[start:end]
print(middle)

Example 5: Remove a prefix if it exists

sku="SKU-004219"
prefix="SKU-"

ifsku.startswith(prefix):
sku=sku[len(prefix):]

print(sku)

Example 6: Split on a delimiter using find()

email="mina@example.com"
at=email.find("@")

ifat==-1:
print("Missing @")
else:
username=email[:at]
domain=email[at+1:]
print(username,domain)

Common mistakes and how to fix them

Mistake 1: Off-by-one errors with the end index

What you might do:

s="python"
print(s[0:3])

Why it surprises you: the end index is excluded, so 0:3 returns 3 characters, not 4.

Fix:

s="python"
print(s[:4])

Mistake 2: Expecting slicing rules to apply to direct indexing

What you might do:

s="EU-42"
print(s[100])

Why it breaks: direct indexing raises IndexError when the index is out of range.

Fix:

s="EU-42"
print(s[:100])# safe
print(s[-100:])# safe

Troubleshooting

If you see an empty string from a slice, check your start and end order. s[3:1] returns "" because the range ends before it starts.

If you get an empty result with a negative step, confirm start > end. s[1:6:-1] cannot move backward from index 1 to 6.

If your delimiter split prints "Missing @", the input does not contain the delimiter. Print repr(email) to spot unexpected characters.

If your slice breaks on short strings, rely on slicing anyway. s[:10] and s[-10:] stay safe even when the string is shorter.

If you need the “middle” between markers, slice using known marker lengths when possible, or use find() when positions vary.


Quick recap

  • Use s[start:end] to take a range. The end index is excluded.
  • Use s[:n] and s[n:] for prefixes and suffixes.
  • Use negative indexes for end-based slices like s[-4:] and s[:-4].
  • Use s[start:end:step] to skip characters or reverse text.
  • Rely on slicing for safe out-of-bounds behavior when taking “up to N” characters.