مرکزی مواد پر جائیں

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. Shouldn't the first character be number 1?"

Emma draws a quick picture:

  title = "Notes"
N o t e s

start here

Position: 0 1 2 3 4

"How far from the start is this character?"

"Position 0 means you are standing at the start, you have not moved. Position 1 means you moved one step forward. It is not counting which character, it is counting how far you have walked from the beginning."

James tries title[0] and gets "N". He tries title[1] and gets "o". It clicks: the index is the distance from the start, not a count starting at 1.


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 far 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

Suppose you need the file extension from a filename like "report.pdf". You want the last 3 characters. With positive indexing, you would have to calculate the length first:

filename: str = "report.pdf"
last_char: str = filename[len(filename) - 1] # "f"

That works, but it is awkward. What if the filename changes to "summary.pdf" (11 characters) or "a.pdf" (5 characters)? You would need len() every time.

Python gives you a shortcut: negative indexing. Instead of counting from the start, count backwards from the end. 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

Now the file extension problem becomes simple. You can grab just the last character:

filename: str = "report.pdf"
last_char: str = filename[-1] # "f"
second_last: str = filename[-2] # "d"
third_last: str = filename[-3] # "p"

Later in this lesson, you will learn slicing (getting multiple characters at once), which makes this even simpler: filename[-3:] gives you "pdf" in one step. For now, the key idea is that negative indices let you work from the end without calculating len().

Use negative indexing whenever you care about the end of a string rather than the beginning. 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've coded before

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]

Press Shift+Tab to enter Plan Mode before predicting.

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

Press Shift+Tab to exit Plan Mode.

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.

If you want to go deeper, run /investigate @index_practice.py in Claude Code and ask why word[1:4] returns 3 characters and not 4.

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.


James grins. "Zero-based indexing felt weird at first. Now it makes sense: the index is how far you have walked from the start."

"And slicing?"

"Start is included, stop is excluded. s[1:4] gives me positions 1, 2, 3. Three characters, not four." He pauses. "But I still cannot change anything. If the title has extra spaces, I can see them with indexing, but I cannot remove them."

"That is what string methods do," Emma says. "Lesson 3. You will learn .strip(), .upper(), .replace(), and a few others that transform strings into new ones."