LambdaLabTM
Computer Science · Class 11 · Data Types
Data TypesSequences⏱️ 12 min read

Strings

You have used strings since your first line of code, and you know the six sequence tricks work on them. Now meet what strings can do that is theirs alone — the methods. And watch closely, because every one of them hands back a new string and leaves the old one exactly as it was.

1What you already know

A string is a sequence of characters in quotes. Single, double or triple quotes — you chose them back in the print chapter. And because it is a sequence, all six common features apply:

string_recap.py
word = 'hello'

print(len(word))
print(word[0])
print(word[-1])
print(word[1:4])
print('hi' + 'there')
print('ha' * 3)
print('ell' in word)
Output
5
h
o
ell
hithere
hahaha
True

2Methods: a string's own tricks

A method is a function that belongs to a value. You write it after the value, with a dot in between: 'hello'.upper(). Same parentheses as always, so you already know it is a function — it just happens to belong to that string.

Note
Function or method? len('hello') — the string goes inside the parentheses. That is a function. 'hello'.upper() — the string comes before the dot. That is a method. Same idea, different way of writing it.

String methods come in four kinds, sorted by the question you are asking. Try each one, and keep half an eye on the amber box on the right.

>>> 'hello'.upper()
'HELLO'
what it did

A new string, every letter in CAPITALS.

and the original?

Untouched. Every single time. A method never edits the string it was called on — it builds something new and hands that back.

Tip
capitalize() vs title(). They sound the same and are not. capitalize() puts one capital at the very front and makes everything else small — so 'RAMESH KUMAR'.capitalize() gives 'Ramesh kumar'. title() capitalises the first letter of every word — so 'ramesh kumar'.title() gives 'Ramesh Kumar'. One is a sentence; the other is a name.
Tip
Why strip() is worth remembering. A space at the end of a word is invisible, and it still counts. If a user types yes with a stray space after it, then 'yes ' == 'yes' is False — and your program says no when the user said yes. strip() takes the blank space off both ends and hands back a clean string, so ' yes '.strip() == 'yes' is True. Spaces inside are left alone: ' a b '.strip() gives 'a b', keeping the one in the middle. Need only one side? lstrip() cleans the left, rstrip() the right.

The trouble with showing this is that spaces are invisible. So print each answer between square brackets — then you can see exactly where the string ends:

stripping.py
typed = '  Ravi  '

print('[' + typed.strip() + ']')
print('[' + typed.lstrip() + ']')
print('[' + typed.rstrip() + ']')
print('[' + typed + ']')
Output
[Ravi]
[Ravi  ]
[  Ravi]
[  Ravi  ]
Key Takeaway
rstrip() is the right end — R for RIGHT. It cleaned the two spaces after Ravi and left the two before it exactly as they were. And the last line proves the point of this whole lesson: typed itself still has spaces on both sides. Not one of the three methods edited it — each handed back a new string.

replace() is the one that takes two things: what to look for, and what to put in its place. It changes every match it finds, not just the first one:

replacing.py
greeting = 'good morning'

print(greeting.replace('o', '0'))
print(greeting.replace('morning', 'evening'))
print(greeting)
Output
g00d m0rning
good evening
good morning

All three os went, because replace() does not stop at the first one. And look at the last line: greeting is still 'good morning'. Like every method on this page, replace() hands you a new string and leaves the original exactly as it was.

Watch Out
There is no toupper() or tolower() in Python. Those are from other languages (C, C++, Java), and students who have seen them elsewhere type them by habit. Python uses upper() and lower(). Write 'hello'.toupper() and you will get AttributeError: 'str' object has no attribute 'toupper'.

3The is-methods: asking, not changing

These all begin with is, and they all answer True or False. They never change anything — they only look and report.

MethodAsksExample
isupper()Is it ALL in capitals?'HELLO'.isupper() → True
islower()Is it all in small letters?'Hello'.islower() → False
isalpha()Is every character a letter?'hello'.isalpha() → True
isdigit()Is every character a digit?'12345'.isdigit() → True
isspace()Is it nothing but blank space?' '.isspace() → True
isalnum()Is every character a letter or a digit?'abc 123'.isalnum() → False
Tip
upper() vs isupper(). One letter changes everything. upper() makes a capitalised copy. isupper() only asks whether it already is — and answers True or False. Change versus ask.
Watch Out
“Every character” means every character. 'abc 123'.isalnum() is False, because a space is neither a letter nor a digit. In the same way '12a'.isdigit() is False — one letter is enough to spoil it — and 'hello world'.isalpha() is False, because of the single space in the middle.

4find() and index() — the same, until they fail

Both tell you where something is. When the thing is there, they give exactly the same answer:

finding.py
word = 'hello'

print(word.find('l'))
print(word.index('l'))
Output
2
2

The difference only appears when the thing is not there — and it is a big one:

finding.py
word = 'hello'

print(word.find('z'))   # not there -> -1, and the program carries on
print(word.index('z'))  # not there -> the program stops here
Output
-1
Traceback (most recent call last):
  File "finding.py", line 4, in <module>
    print(word.index('z'))  # not there -> the program stops here
          ^^^^^^^^^^^^^^^
ValueError: substring not found
Key Takeaway
find() is polite: not there? It shrugs and returns -1, and your program carries on. index() is strict: not there? It raises a ValueError and stops. Use find() when the thing might be missing. Use index() when it should never be.

Sometimes you do not need to know where something is — only whether the string begins or ends with it. That is what startswith() and endswith() are for, and they answer True or False:

ends.py
name = 'Ramesh Kumar'
filename = 'report.txt'

print(name.startswith('Ram'))
print(name.endswith('Kumar'))
print(filename.endswith('.txt'))
print(name.startswith('ram'))
Output
True
True
True
False
Watch Out
Look at the last line. 'Ramesh Kumar' does begin with ram as far as your eye is concerned, but the answer is False — a capital R and a small r are two different characters. Every string method that compares letters works this way. If the capitals do not matter to you, compare in one case: name.lower().startswith('ram') is True.

5split(), partition() and join()

These three move between a string and a list. split() and partition() break a string apart; join() glues it back together.

split_join.py
letters = 'a,b,c'.split(',')
parts = 'good morning'.partition(' ')
joined = '-'.join(['a', 'b', 'c'])

print(letters)
print(parts)
print(joined)
Output
['a', 'b', 'c']
('good', ' ', 'morning')
a-b-c
split() — cuts at EVERY separator

Gives back a list of the pieces. The separator itself is thrown away.

partition() — cuts at the FIRST one only

Gives back a tuple of three: what came before, the separator itself, and what came after. Nothing is thrown away.

Watch Out
join() is written backwards from what you expect. The glue comes first, and the list goes inside the parentheses: '-'.join(['a', 'b', 'c']). Read it aloud as: “using a dash, stick these together”. Almost everybody writes it the other way round the first time.

6Try it at the prompt

Python prompt — interactive mode
# Every method above works here. Call one on a string and see what comes back.
>>>
try

7The original never changes

This is the most important sentence in the lesson. A string method never edits the string it was called on. It builds a new string and gives that back.

unchanged.py
word = 'hello'

print(word.upper())   # a new string comes back
print(word)           # the original is untouched
Output
HELLO
hello

Look at that carefully. We shouted at 'hello', and it politely handed back a capitalised copy. Then we asked for 'hello' again — and it is still small, still itself, entirely unbothered.

Key Takeaway
A string cannot be changed. Ever. Methods like upper() do not change it — they return a new string. This has a proper name, immutable, and it gets a lesson of its own shortly.

8in — is it in there?

This one is not a string method at all — it is the membership operator from the sequences lesson, and it works on lists and tuples too. Ask whether a character (or a smaller piece of text) appears inside a string. The answer comes back as a boolean — True or False. Unlike find(), it does not tell you where — only whether.

is_it_there.py
word = 'hello'

print('e' in word)
print('z' in word)
print('ell' in word)
Output
True
False
True

9Escape sequences — the backslash

An escape sequence is a short code you write inside a string. It always begins with a backslash (\), followed by one or more characters. You type two symbols, but Python does not read them one by one — it treats the pair as one single character, and each pair has one fixed job.

What you type · what Python stores
\
backslash
+
n
code letter
=
1 character
a new line
\ — the backslash

Warns Python: do not read the next character in the usual way.

n — the code letter

Says which special character you want. n is a new line, t is a tab.

They exist because some characters cannot simply be typed. Here is the smallest example. You want to print It's mine, so you write it in single quotes:

quotes.py
print('It's mine')
Output
  File "quotes.py", line 1
    print('It's mine')
                    ^
SyntaxError: unterminated string literal (detected at line 1)

Python is not being difficult. It read the second quote — the one in It's — and decided the string ended there. Everything after it made no sense.

The fix is the backslash. Write \' and Python knows that quote is part of the text, not the end of it.

quotes.py
print('It\'s mine')       # \' means: a plain quote, not the end
print("It's mine")        # or just use the other kind of quotes
print("He said \"hi\"")
Output
It's mine
It's mine
He said "hi"

The same backslash does a second job. Some characters cannot be typed inside a string at all — you cannot press Enter in the middle of one, and you cannot type a Tab and expect it to survive. So Python gives you short codes for them.

You writeYou getUsed for
\na new linemoving to the next line
\ta tablining up columns
\\one backslashwhen you really want a \
\'a single quoteinside a '...' string
\"a double quoteinside a "..." string
\ba backspacerare, but in your syllabus
\ra carriage returnback to the start of the line
\0a null characterrare, but in your syllabus

\n and \t are the two you will actually use. One breaks a line, the other lines things up in columns:

escapes.py
print('Name\tClass\tMarks')
print('Ramesh\t11\t87')
print('line one\nline two')
Output
Name	Class	Marks
Ramesh	11	87
line one
line two
Key Takeaway
An escape sequence is one character, not two. You type two symbols, but Python stores a single character — so len('\n') is 1, and len('a\nb') is 3. This is a favourite exam question.
counting.py
newline = '\n'
tab = '\t'
backslash = '\\'

print(len(newline))
print(len(tab))
print(len(backslash))
print(len('a\nb'))
Output
1
1
1
3

The trap: Windows file paths

Windows writes paths with backslashes, like C:\notes\table.txt. Put that straight into a string and Python reads \n and \t as escape sequences — and your path falls apart.

paths.py
path = 'C:\notes\table.txt'
print(path)              # \n became a new line, \t became a tab!

safe = 'C:\\notes\\table.txt'
print(safe)              # doubled backslashes: correct, but ugly

raw = r'C:\notes\table.txt'
print(raw)               # an r in front: much easier
Output
C:
otes	able.txt
C:\notes\table.txt
C:\notes\table.txt
Tip
Putting r in front of a string makes it a raw string: every backslash inside stays exactly as you typed it, and no escape sequence is applied. Handy for file paths.

10Recap

MethodDoesGives back
upper()ALL CAPITALSa new string
lower()all small lettersa new string
capitalize()First letter only — rest made smalla new string
title()First Letter Of Each Worda new string
strip()removes spaces at both endsa new string
lstrip() / rstrip()left end only / right end onlya new string
replace(a, b)swaps every a for ba new string
isupper()is it ALL capitals?True / False
islower()is it all small letters?True / False
isdigit()is every character a digit?True / False
isspace()is it only blank space?True / False
isalpha()is every character a letter?True / False
isalnum()letters and digits only?True / False
startswith(x)does it begin with x?True / False
endswith(x)does it end with x?True / False
count(x)how many times x appearsa number
find(x)position of first x — gives -1 if absenta number
index(x)position of first x — ERROR if absenta number
split(sep)cuts at every separatora list
partition(sep)cuts at the first separator onlya tuple of 3
sep.join(list)glues a list into one stringa new string

And the escape sequences — every one of them a single character:

Escape sequenceGives youLength
\na new line1 character
\ta tab1 character
\\one backslash1 character
\'a single quote, inside '...'1 character
\"a double quote, inside "..."1 character
\ba backspace1 character
\ra carriage return1 character
\0a null character1 character
Key Takeaway
A method is written after the value with a dot: 'hello'.upper(). String methods always return a new value; the original string is never edited. An escape sequence is written inside the string itself: two symbols starting with \, stored as one character. Put r in front of a string to switch them all off.
Quick Check

After 'hello'.upper(), what is 'hello'?

Quick Check

What does 'hello'.count('l') give?

Quick Check

Which is a method, not a function?

Quick Check

'hello'.find('z') gives -1. What does 'hello'.index('z') do?

Quick Check

What does 'RAMESH KUMAR'.capitalize() give?

Quick Check

What is 'abc 123'.isalnum()?

Quick Check

How do you join ['a', 'b', 'c'] into 'a-b-c'?

Quick Check

What is len('a\\nb')?

Quick Check

What does print('C:\\notes') show?