Your name, your school's name, a WhatsApp message, a password, an email address โ all of these are text. In Python, text is stored as a string, and almost every real program has to work with text: checking a password, counting words in an essay, or finding a name in a list. This chapter shows how to visit each character of a string, how to cut out part of a string with slicing, what string operators like +, * and in do, and which built-in string methods save us from writing long programs.
Focus especially on slicing (with negative indices and steps), the string methods table, find() vs index(), split() vs partition(), and string programs (count vowels, palindrome, etc.). Practise output-based questions on slicing and methods.
9.1 ๐ Introduction
A string is a sequence of characters enclosed in single quotes (' '), double quotes (" ") or triple quotes (''' ''' / """ """). A character can be a letter, digit, space, symbol or even an emoji.
s1 = 'Hello'
s2 = "Python 3.12"
s3 = """Line one
Line two"""
s4 = "" # an empty string โ length 0
You learnt in the Data Handling chapter that each character of a string has an index, and Python supports two-way indexing:
String : C O M P U T E R
Forward : 0 1 2 3 4 5 6 7
Backward : -8 -7 -6 -5 -4 -3 -2 -1
word = "COMPUTER"
print(word[0], word[5], word[-1], word[-3]) # C T R T
print(len(word)) # 8
For a string of length n: forward indices go from 0 to n โ 1, and backward indices go from โ1 to โn. The last character is always s[-1] or s[len(s) - 1]. Using an index outside this range gives an IndexError.
9.1.1 Strings are Immutable ๐
Once a string is created, its characters cannot be changed in place.
name = "Rahul"
# name[0] = "M" # โ TypeError: 'str' object does not support item assignment
name = "M" + name[1:] # โ
create a NEW string instead
print(name) # Mahul
Methods like upper() or replace() do NOT change the original string โ they return a NEW string. If you don't store the result, the change is lost!
s = "hello"
s.upper() # result thrown away
print(s) # hello โ unchanged!
s = s.upper() # โ
store the new string
print(s) # HELLO9.2 ๐ถ Traversing a String
Traversing means visiting each character of a string one by one, usually with a loop.
Method 1 โ Directly over the characters:
for ch in "INDIA":
print(ch, end=" ")
# Output: I N D I A
Method 2 โ Using the index with range(len(s)):
s = "INDIA"
for i in range(len(s)):
print(i, s[i])
0 I
1 N
2 D
3 I
4 A
Method 3 โ Printing a string in reverse:
s = "PYTHON"
for i in range(len(s) - 1, -1, -1):
print(s[i], end="")
# Output: NOHTYP
for ch in s
Gives each CHARACTER directly; simplest way
When the position is not neededfor i in range(len(s))
Gives each INDEX; the character is s[i]
When you need the position too9.3 โ String Operators
9.3.1 Concatenation Operator + ๐
The + operator joins two strings end to end.
first = "Good"
second = "Morning"
print(first + " " + second) # Good Morning
print("10" + "20") # 1020 (text join, NOT addition!)
Both operands of + must be strings. "Age: " + 16 gives TypeError: can only concatenate str (not "int") to str. Convert first: "Age: " + str(16).
9.3.2 Replication Operator * ๐
The * operator repeats a string a given number of times. One operand must be a string and the other an integer.
print("Ha" * 3) # HaHaHa
print(3 * "-=") # -=-=-=
print("abc" * 0) # (empty string)
9.3.3 Membership Operators in and not in ๐
They check whether a character or substring is present in a string, and return True or False.
s = "Informatics"
print("for" in s) # True
print("For" in s) # False (case-sensitive!)
print("z" not in s) # True
9.3.4 Comparison Operators โ๏ธ
Strings can be compared with ==, !=, <, >, <=, >=. Python compares them character by character using the characters' Unicode (ASCII) values.
| Characters | Unicode / ASCII values |
|---|---|
'0' to '9' |
48 to 57 |
'A' to 'Z' |
65 to 90 |
'a' to 'z' |
97 to 122 |
Space ' ' |
32 |
print("apple" < "apricot") # True ('p' = 112 < 'r' = 114 at index 2)
print("Zebra" < "apple") # True ('Z' = 90 < 'a' = 97)
print("abc" < "abcd") # True (a shorter prefix is smaller)
print("10" < "9") # True ('1' = 49 < '9' = 57) โ text, not numbers!
ord() and chr() convert between a character and its Unicode value:
print(ord("A")) # 65
print(chr(97)) # a
print(chr(ord("a") - 32)) # A
Digits start at 48, capitals at 65, small letters at 97. So in string comparison: digits < CAPITALS < small letters. Remember: "Numbers before BIG, BIG before small"!
"What is the output of print('Python' > 'python')?" โ 1-mark question!
Answer: False โ 'P' has the value 80 and 'p' has 112, so 'Python' is smaller than 'python'.
9.4 โ๏ธ String Slicing
Slicing extracts a part (substring) of a string.
Syntax: string[start : stop : step]
start
Index where the slice begins; INCLUDED (default: beginning of the string)
Includedstop
Index where the slice ends; EXCLUDED (default: end of the string)
Excludedstep
Jump between characters (default 1); a negative step goes backwards
Can be negativeLet's slice s = "PROGRAMMING":
P R O G R A M M I N G
0 1 2 3 4 5 6 7 8 9 10
-11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1
| Slice | Result | Explanation |
|---|---|---|
s[0:4] |
'PROG' |
indices 0, 1, 2, 3 |
s[3:7] |
'GRAM' |
indices 3 to 6 |
s[:3] |
'PRO' |
from the start up to index 2 |
s[7:] |
'MING' |
from index 7 to the end |
s[:] |
'PROGRAMMING' |
a full copy |
s[-4:] |
'MING' |
last 4 characters |
s[-7:-3] |
'RAMM' |
indices โ7 to โ4 |
s[::2] |
'PORMIG' |
every 2nd character |
s[1:9:3] |
'RRM' |
indices 1, 4, 7 |
s[::-1] |
'GNIMMARGORP' |
the whole string reversed |
s[8:2:-2] |
'IMR' |
indices 8, 6, 4 (going backwards) |
s[5:2] |
'' |
empty โ can't go forward from 5 to 2 |
s[4:100] |
'RAMMING' |
stop beyond the end is allowed |
start is included, stop is excluded โ exactly like range(). The number of characters in s[a:b] (step 1) is b โ a. Also, s[:n] + s[n:] always gives back the full string s.
s[20] gives an IndexError if the string is shorter, but s[2:20] simply stops at the end of the string. Slicing is forgiving; indexing is not!
Slicing output questions usually carry 1 to 2 marks. Always write the index numbers (both forward and backward) under the string first, then pick the characters. For a negative step, move from right to left, and start must be to the right of stop.
9.5 ๐งฐ Built-in String Functions and Methods
Python provides many ready-made methods for strings. They are called using the dot notation: string.method(). The only common one that is a function (not a method) is len().
9.5.1 Length, Case-Changing and Counting ๐
| Method | Description | Example | Result |
|---|---|---|---|
len(s) |
Number of characters | len("Hello World") |
11 |
s.capitalize() |
First character capital, the rest small | "hELLO wORLD".capitalize() |
'Hello world' |
s.title() |
First letter of EVERY word capital | "good morning india".title() |
'Good Morning India' |
s.lower() |
All letters in lowercase | "PyThOn".lower() |
'python' |
s.upper() |
All letters in uppercase | "PyThOn".upper() |
'PYTHON' |
s.swapcase() |
Swaps the case of each letter | "PyThOn".swapcase() |
'pYtHoN' |
s.count(sub) |
How many times sub occurs (non-overlapping) |
"banana".count("a") |
3 |
s = "the quick brown fox"
print(s.capitalize()) # The quick brown fox
print(s.title()) # The Quick Brown Fox
print(s.count("o")) # 2
print(s.count("the")) # 1
capitalize() makes only the first character of the whole string capital (and the rest small). title() capitalises the first letter of every word. Don't mix them up!
9.5.2 Searching: find(), index(), startswith(), endswith() ๐
| Method | Description | Example | Result |
|---|---|---|---|
s.find(sub) |
Lowest index where sub is found; โ1 if not found |
"banana".find("an") |
1 |
s.find(sub, start, end) |
Searches only within s[start:end] |
"banana".find("an", 2) |
3 |
s.index(sub) |
Same as find(), but raises ValueError if not found |
"banana".index("n") |
2 |
s.startswith(sub) |
True if the string begins with sub |
"python.py".startswith("py") |
True |
s.endswith(sub) |
True if the string ends with sub |
"report.pdf".endswith(".pdf") |
True |
s = "banana"
print(s.find("na")) # 2
print(s.find("xyz")) # -1
# print(s.index("xyz")) # โ ValueError: substring not found
find() vs index() โ The Critical Comparison:
| Feature | find() |
index() |
|---|---|---|
| Substring found | Returns its lowest index | Returns its lowest index |
| Substring NOT found | Returns โ1 | Raises ValueError |
| Safer to use when unsure | โ Yes | โ No (program may crash) |
"Differentiate between find() and index()." โ 2-mark question!
Answer: Both return the lowest index at which a substring occurs. If the substring is not found, find() returns โ1, whereas index() raises a ValueError.
9.5.3 Checking Methods: is...() โ
These methods test the characters of a string and return True or False. They all return False for an empty string.
| Method | Returns True if... | True example |
False example |
|---|---|---|---|
isalpha() |
all characters are letters | "Python" |
"Python3" |
isdigit() |
all characters are digits | "2025" |
"20.25" |
isalnum() |
all characters are letters or digits | "Class11" |
"Class 11" (space!) |
islower() |
all letters are lowercase (at least one letter) | "abc123" |
"Abc" |
isupper() |
all letters are uppercase (at least one letter) | "CBSE2025" |
"Cbse" |
isspace() |
all characters are whitespace (space, tab, newline) | " " |
" a " |
print("Hello World".isalpha()) # False (the space is not a letter)
print("12345".isdigit()) # True
print("-5".isdigit()) # False ('-' is not a digit)
print("abc123".islower()) # True (digits are ignored; the letters are lowercase)
print("".isalpha()) # False (empty string)
alpha = alphabets ยท digit = digits ยท alnum = alphabets + numbers. A space makes ALL three of them False!
9.5.4 Stripping Whitespace: strip(), lstrip(), rstrip() ๐งฝ
| Method | Removes | Example (s = " Hi there ") |
Result |
|---|---|---|---|
s.strip() |
Leading and trailing spaces | s.strip() |
'Hi there' |
s.lstrip() |
Left (leading) spaces only | s.lstrip() |
'Hi there ' |
s.rstrip() |
Right (trailing) spaces only | s.rstrip() |
' Hi there' |
You can also pass the characters to remove:
print("xxHelloxx".strip("x")) # Hello
print("www.cbse.gov.in".lstrip("w.")) # cbse.gov.in
print("Hello!!!".rstrip("!")) # Hello
strip() removes characters only from the two ends, never from the middle. " Hi there ".strip() gives 'Hi there' โ the spaces between the words stay.
9.5.5 Replacing, Splitting, Joining and Partitioning ๐ง
| Method | Description | Example | Result |
|---|---|---|---|
s.replace(old, new) |
Replaces ALL occurrences of old with new |
"banana".replace("a", "o") |
'bonono' |
s.split() |
Splits at whitespace; returns a list | "I love Python".split() |
['I', 'love', 'Python'] |
s.split(sep) |
Splits at the given separator | "10-20-30".split("-") |
['10', '20', '30'] |
sep.join(seq) |
Joins the strings of a sequence using sep |
"-".join(["10", "20", "30"]) |
'10-20-30' |
s.partition(sep) |
Splits at the FIRST sep into a 3-part tuple |
"a=b=c".partition("=") |
('a', '=', 'b=c') |
sentence = "Python is easy and Python is fun"
print(sentence.replace("Python", "Java"))
# Java is easy and Java is fun
words = sentence.split()
print(len(words)) # 7 (number of words)
print("*".join("ABC")) # A*B*C
print(" ".join(["Hello", "World"])) # Hello World
print("user@gmail.com".partition("@"))
# ('user', '@', 'gmail.com')
print("hello".partition("@"))
# ('hello', '', '') โ separator not found
split() vs partition() โ The Critical Comparison:
| Feature | split() |
partition() |
|---|---|---|
| Returns | A list | A tuple of exactly 3 items |
| Splits at | EVERY occurrence of the separator | Only the FIRST occurrence |
| Separator in the result? | โ No | โ Yes (as the middle item) |
| Separator not found | List with the whole string | (whole string, '', '') |
Example with "a-b-c" and "-" |
['a', 'b', 'c'] |
('a', '-', 'b-c') |
"Differentiate between split() and partition()." โ 2-mark question!
Answer: split() breaks the string at every occurrence of the separator and returns a list without the separator. partition() breaks the string at the first occurrence only and returns a tuple of three parts: the part before the separator, the separator itself, and the part after it.
In join(), the separator comes first and the sequence goes inside the brackets: "-".join(lst) โ
, NOT lst.join("-") โ. Also, every item of the sequence must be a string โ "-".join([1, 2, 3]) gives a TypeError.
9.6 ๐ป Important String Programs
Code Example: count_characters.py
# Count vowels, consonants, digits, spaces and uppercase letters
s = input("Enter a string: ")
vowels = consonants = digits = spaces = upper = 0
for ch in s:
if ch.isalpha():
if ch.lower() in "aeiou":
vowels += 1
else:
consonants += 1
if ch.isupper():
upper += 1
elif ch.isdigit():
digits += 1
elif ch.isspace():
spaces += 1
print("Vowels:", vowels)
print("Consonants:", consonants)
print("Digits:", digits)
print("Spaces:", spaces)
print("Uppercase letters:", upper)
Input: CBSE Class 11 Exam
Vowels: 4
Consonants: 9
Digits: 2
Spaces: 3
Uppercase letters: 6
Code Example: palindrome_string.py
s = input("Enter a string: ")
if s.lower() == s.lower()[::-1]:
print(s, "is a palindrome")
else:
print(s, "is not a palindrome")
# Input Madam โ Madam is a palindrome
# Input Python โ Python is not a palindrome
Code Example: palindrome_without_slicing.py
# The same check using a loop (asked when slicing is not allowed)
s = input("Enter a string: ")
is_palin = True
n = len(s)
for i in range(n // 2):
if s[i] != s[n - 1 - i]:
is_palin = False
break
print("Palindrome" if is_palin else "Not a palindrome")
# Input level โ Palindrome
Code Example: word_stats.py
# Count words and find the longest word in a sentence
sentence = input("Enter a sentence: ")
words = sentence.split()
print("Number of words:", len(words))
longest = ""
for w in words:
if len(w) > len(longest):
longest = w
print("Longest word:", longest)
# Input: Python makes programming simple
# Number of words: 4
# Longest word: programming
Code Example: toggle_case.py
# Convert uppercase to lowercase and vice versa without swapcase()
s = input("Enter a string: ")
result = ""
for ch in s:
if ch.isupper():
result += ch.lower()
elif ch.islower():
result += ch.upper()
else:
result += ch
print(result)
# Input: Hello World 2025 โ hELLO wORLD 2025
Code Example: initials.py
# Print the initials of a full name
name = input("Enter full name: ")
initials = ""
for part in name.split():
initials += part[0].upper() + "."
print(initials)
# Input: mohandas karamchand gandhi โ M.K.G.
"Write a program to count vowels / check palindrome / count words" โ 3-mark programs, asked very often!
Always: (1) take input, (2) initialise the counters to 0 before the loop, (3) traverse with for ch in s, and (4) use methods like isalpha(), isdigit(), isupper() instead of long comparisons.
โ ๏ธ Common Errors and Misconceptions
| Mistake | What's Wrong | Correct Understanding |
|---|---|---|
โ s[0] = 'X' to change a string |
Strings are immutable | โ
Build a new string: s = 'X' + s[1:] |
โ s.upper() changes s |
Methods return a NEW string | โ
Write s = s.upper() |
โ s[2:5] includes index 5 |
stop is excluded | โ It gives indices 2, 3 and 4 |
โ s[10:20] on a short string gives an error |
Slicing never raises IndexError | โ
It returns whatever exists (maybe '') |
โ "10" + 5 gives 15 |
Can't join str and int | โ
TypeError; use int("10") + 5 or "10" + str(5) |
โ find() raises an error when not found |
That's index() |
โ
find() returns โ1; index() raises ValueError |
โ capitalize() and title() are the same |
Different scope | โ
capitalize() โ only the first letter of the string; title() โ first letter of every word |
โ "-5".isdigit() is True |
- is not a digit |
โ
It is False |
โ lst.join("-") |
Wrong order | โ
"-".join(lst) |
โ "Apple" > "apple" is True |
'A' = 65 < 'a' = 97 | โ
It is False |
๐ Quick Revision
String Basics:
- A sequence of characters in quotes; immutable
- Indices: 0 to n โ 1 (forward), โ1 to โn (backward)
- Traverse with
for ch in sorfor i in range(len(s))
Operators:
| Operator | Use | Example โ Result |
|---|---|---|
+ |
Concatenation | "Hi" + "5" โ 'Hi5' |
* |
Replication | "ab" * 3 โ 'ababab' |
in / not in |
Membership | "th" in "Python" โ True |
<, == โฆ |
Comparison (Unicode) | "A" < "a" โ True |
Slicing s[start:stop:step]: start included ยท stop excluded ยท s[::-1] reverses ยท never an IndexError
Methods at a Glance:
- Case:
capitalize(),title(),lower(),upper(),swapcase() - Search:
count(),find()(โ1),index()(ValueError),startswith(),endswith() - Check:
isalpha(),isdigit(),isalnum(),islower(),isupper(),isspace() - Clean:
strip(),lstrip(),rstrip() - Transform:
replace(),split()โ list,join(),partition()โ 3-tuple
ASCII values: '0' = 48 ยท 'A' = 65 ยท 'a' = 97 ยท space = 32
๐ฏ Sample Exam Questions
Q1: Very Short Answer [1 mark each]
a) What is the output of print("CBSE"[::-1])?
โ ESBC
b) What does "hello".find("z") return?
โ -1
c) What is the output of print("ab" * 2 + "c")?
โ ababc
d) Which method returns a tuple of three parts?
โ partition()
e) What is the output of print(len("Hi there!"))?
โ 9
Q2: Slicing Output [2 marks]
Q: If s = "INFORMATICS", write the output of:
a) s[2:6] b) s[-4:] c) s[::3] d) s[7:1:-2]
Answer:
I N F O R M A T I C S
0 1 2 3 4 5 6 7 8 9 10
a) 'FORM'
b) 'TICS'
c) 'IOAC' (indices 0, 3, 6, 9)
d) 'TMO' (indices 7, 5, 3)
Q3: Output Based [2 marks]
Q: Write the output of the following code:
s = "Python Programming"
print(s.count("o"), s.find("P", 1), s.upper()[7:10])
print(s.split("o"))
print(s.partition(" "))
Answer:
2 7 PRO
['Pyth', 'n Pr', 'gramming']
('Python', ' ', 'Programming')
Q4: Output Based [3 marks]
Q: Write the output of the following code:
msg = "Board@2026"
new = ""
for ch in msg:
if ch.isupper():
new += ch.lower()
elif ch.islower():
new += ch.upper()
elif ch.isdigit():
new += str(int(ch) + 1)
else:
new += "#"
print(new)
Answer:
bOARD#3137
(Letters swap case, each digit increases by 1 โ 2026 becomes 3137, and '@' becomes '#'.)
Q5: Program [3 marks]
Q: Write a program to input a string and print how many times each vowel occurs in it.
s = input("Enter a string: ").lower()
for v in "aeiou":
print(v, ":", s.count(v))
Input: Education is important
a : 2
e : 1
i : 3
o : 2
u : 1
โ๏ธ Practice Problems
-
Write the output of the following, given
s = "COMPUTER SCIENCE": (a)s[3:8](b)s[-7:](c)s[::4](d)s[10:2:-3] -
Differentiate between
isalpha(),isdigit()andisalnum()with one example each. -
Write a program to input a string and print it with every word's first letter in uppercase, WITHOUT using
title(). -
Write a program to count the number of times the word "the" appears in a sentence (as a whole word, ignoring case).
-
Write a program to remove all the vowels from a string entered by the user.
-
Write a program that inputs an email address and prints the username and the domain name separately using
partition(). -
Write the output of: (a)
" Hello ".strip()(b)"a,b,,c".split(",")(c)"-".join("2026")(d)"banana".replace("an", "AN", 1) -
Write a program to check whether a password is valid: at least 8 characters, with at least one uppercase letter, one lowercase letter and one digit.
-
Explain with an example why
s[20]gives an error buts[5:20]does not, fors = "Python". -
Write a program to print the following pattern for the word "PYTHON":
P PY PYT PYTH PYTHO PYTHON