Skip to main content

Indexing and Slicing

In Lesson 1, you created strings and measured their length. Now you reach inside them. Every character in a string has a position, and Python lets you access any character by its position number.

James needs to extract the first letter of a note title for an alphabetical index. He tries title[1], expecting the first character.

Emma shakes her head. "Python counts from zero. The first character is title[0], not title[1]."

"Why? That makes no sense."

"It makes perfect sense once you think about positions as offsets from the start. The first character is zero steps from the beginning. The second is one step. The third is two steps."

James tries title[0] and gets the right answer. Zero-based indexing is strange at first, but it becomes second nature with practice.


Zero-Based Indexing

Every character in a string has a position number called an index. Python starts counting at 0:

title: str = "SmartNotes"
# S m a r t N o t e s
# Position: 0 1 2 3 4 5 6 7 8 9

To access a single character, use square brackets with the index:

title: str = "SmartNotes"
title[0]
title[1]
title[5]
title[9]

Output:

S
m
N
s
If you're new to programming

Zero-based indexing means the first item is at position 0, not position 1. This is a universal convention in Python (and most programming languages). Think of it as "how many steps from the start." The first character is 0 steps away, the second is 1 step away, and so on.

If you try to access an index that does not exist, Python raises an error:

title: str = "SmartNotes"  # 10 characters, indices 0-9
title[10] # IndexError: string index out of range

Output:

IndexError: string index out of range

The string has 10 characters with indices 0 through 9. Index 10 does not exist.


Negative Indexing

Python also lets you count from the end using negative numbers. The last character is -1, the second-to-last is -2, and so on:

title: str = "SmartNotes"
# S m a r t N o t e s
# Positive: 0 1 2 3 4 5 6 7 8 9
# Negative: -10 -9 -8 -7 -6 -5 -4 -3 -2 -1
title: str = "SmartNotes"
title[-1]
title[-2]
title[-5]

Output:

s
e
N

Negative indexing is useful when you want the last character without knowing the string length. s[-1] always gives you the last character, regardless of how long the string is.


Slicing: Extracting Substrings

A slice extracts a portion of a string. The syntax is s[start:stop], where start is the first index included and stop is the first index excluded:

title: str = "SmartNotes"
title[0:5]
title[5:10]
title[1:4]

Output:

Smart
Notes
mar

The key rule: start is included, stop is excluded. title[0:5] gives you characters at positions 0, 1, 2, 3, 4 (five characters), but not position 5.

Shorthand Slices

You can omit start or stop for common patterns:

title: str = "SmartNotes"

# From the beginning to position 5 (exclusive)
title[:5]

# From position 5 to the end
title[5:]

# The entire string (copy)
title[:]

Output:

Smart
Notes
SmartNotes
SliceMeaningCharacters Included
s[:5]First 5 charactersPositions 0-4
s[5:]From position 5 to the endPositions 5 through last
s[1:4]Positions 1, 2, 3Three characters
s[:]Entire stringAll characters

Slicing Safety

Unlike indexing, slicing never raises an error for out-of-range values. Python quietly adjusts:

title: str = "SmartNotes"  # 10 characters
title[0:100]
title[50:100]

Output:

SmartNotes

title[0:100] returns the entire string (stops at the end). title[50:100] returns an empty string (start is beyond the end). No IndexError. This safety feature means slicing is forgiving even when you do not know the exact string length.

If you already know arrays from another language

Python's slice behavior (start:stop, stop-exclusive, out-of-range safe) is similar to JavaScript's slice() method and Go's slice syntax. If you are used to inclusive ranges from other languages, remember: Python's stop index is always exclusive.


PRIMM-AI+ Practice: Predicting Positions

Predict [AI-FREE]

Look at these indexing and slicing expressions. Without running anything, predict the exact result of each one. Write your predictions and a confidence score from 1 to 5 before checking.

word: str = "Python"

result1: str = word[0]
result2: str = word[-1]
result3: str = word[1:4]
result4: str = word[:3]
result5: str = word[3:]
Check your predictions

result1: "P". Index 0 is the first character.

result2: "n". Index -1 is the last character. "Python" ends with "n".

result3: "yth". Positions 1, 2, 3 (stop at 4, exclusive). "Python".

result4: "Pyt". From the start through position 2. "Python".

result5: "hon". From position 3 to the end. "Python".

If you got 4-5 correct, your indexing intuition is strong. The most common mistake is forgetting that the stop index is exclusive: word[1:4] gives 3 characters, not 4.

Run

Create a file called index_practice.py with the expressions above. Add print() calls for each one. Run it with uv run python index_practice.py. Compare the output to your predictions.

Investigate

For any prediction that was wrong, draw the string on paper with index numbers above each character. Circle the characters included in the slice. Write one sentence explaining the start-inclusive, stop-exclusive rule.

Modify

Change word to "SmartNotes" (10 characters). Predict the results of the same five expressions. Does word[3:] still return "hon"? (It should not; the string changed.) Run your modified file to check.

Make [Mastery Gate]

Given the string title: str = "Chapter 48", write 3 slice expressions that extract:

  1. The word "Chapter" (first 7 characters)
  2. The number "48" (last 2 characters)
  3. The single character "4"

Run uv run python on your file to verify. Do not look at examples first.


Try With AI

Opening Claude Code

If Claude Code is not already running, open your terminal, navigate to your SmartNotes project folder, and type claude. If you need a refresher, Chapter 44 covers the setup.

Prompt 1: Test Your Mental Model

I'm learning Python string indexing. Here is my understanding:
"s[0] is the first character, s[-1] is the last character,
and s[1:4] gives characters at positions 1, 2, and 3."
Is this correct? What common mistakes should I watch for?

Read AI's response. Did it mention the stop-exclusive rule? Did it warn about IndexError for single-character access versus the safety of slicing? Compare its answer to what you learned in this lesson.

What you're learning: You are testing whether your mental model of indexing is complete by letting AI probe for gaps. This habit prevents bugs when you later read AI-generated code that uses slicing.

Prompt 2: Generate Slicing Examples

Create 5 Python examples that demonstrate string slicing
on the word "SmartNotes". Each example should extract a
different meaningful substring (like "Smart", "Notes",
or a single character). Include the expected output as
a comment on each line.

Read AI's output. Verify each slice by counting character positions. Did AI get the start and stop indices right? If any slice is wrong, tell AI which one and explain the correct indices.

What you're learning: You are verifying AI-generated indexing against the position rules from this lesson. Catching off-by-one errors in AI output is a skill you will use constantly.


Key Takeaways

  1. Python uses zero-based indexing. The first character is at position 0, not 1. Think of the index as "steps from the start."

  2. Negative indices count from the end. s[-1] is the last character, s[-2] is the second-to-last. Useful when you do not know the string length.

  3. Slices use start-inclusive, stop-exclusive. s[1:4] gives characters at positions 1, 2, 3 (three characters, not four). Omit start or stop for shorthand: s[:5], s[5:].

  4. Slicing never raises IndexError. Out-of-range values are quietly adjusted. s[0:100] returns the whole string; s[50:100] returns an empty string.


Looking Ahead

You can now access individual characters and extract substrings. In Lesson 3, you transform entire strings: .upper() converts to uppercase, .strip() removes whitespace, and .split() breaks a string into a list. These methods are your tools for cleaning and processing text data.