8b. Prof. Rosenthal’s Additions#

Additions to Chapter 8: Strings and Regular Expressions: more string methods. Chapter 8 uses a few string methods (upper(), startswith(), endswith(), strip(), count() and replace()), but it does not explain all of them. This page explains them, and shows more methods, with examples. Read this page after the chapter. The practice questions at the end have answers: try each question first, then open its Answer.

Run this page on Colab

Run the setup cell below first. In Colab, it downloads thinkpython.py, which lets this page show the errors of some examples without stopping the page.

from os.path import basename, exists

def download(url):
    filename = basename(url)
    if not exists(filename):
        from urllib.request import urlretrieve

        local, _ = urlretrieve(url, filename)
        print("Downloaded " + str(local))
    return filename

download('https://github.com/AllenDowney/ThinkPython/raw/v3/thinkpython.py');

import thinkpython

Where to look up the string methods#

  • The official reference: String Methods, in the Python documentation. This is the complete and exact list of the string methods. It is written for people who already know Python, so you probably will not understand all of it now. That is OK: it is the official reference, and it will make more sense as the course continues.

  • An easier list: Python String Methods, on Programiz. It gives a one-line description of each method. Click the name of a method to see a page with examples.

On this page, the name of each method is a link to its entry in the official reference.

This page does not show every string method. Some of them use lists, tuples or dictionaries, which later chapters explain.

A reminder: how to call a method#

Chapter 8 calls a method with the dot operator: word.upper(). The general form is:

STRING.METHOD(ARGUMENTS)

STRING is any string: a variable, a string in quotes, or an expression that makes a string.

word = 'banana'
word.upper()
'BANANA'
'banana'.upper()
'BANANA'

Strings are immutable (Chapter 8), so a string method never changes the string. It returns a new string. After the call, word has the same value as before. (Only the value of the last line is displayed.)

word = 'banana'
word.upper()
word
'banana'

To keep the result, assign it to a variable. You can assign it to the same variable:

word = 'banana'
word = word.upper()
word
'BANANA'

Changing upper case and lower case#

The five methods in this section return a copy of the string in which the case of the letters is changed. Characters that are not letters (digits, spaces and punctuation) do not change. None of these methods takes an argument: the parentheses are always empty.

Quick summary. Each line shows a call, and the value that it returns. The details of each method are below.

text                'the cAT in THE hat'
text.upper()        'THE CAT IN THE HAT'
text.lower()        'the cat in the hat'
text.capitalize()   'The cat in the hat'
text.title()        'The Cat In The Hat'
text.swapcase()     'THE Cat IN the HAT'

Details: upper, lower, capitalize, title and swapcase#

To hide or show the details of each method, click the arrow next to this heading.

upper()#

STRING.upper() returns a copy of STRING with all the letters in upper case.

text = 'the cAT in THE hat'
text.upper()
'THE CAT IN THE HAT'

lower()#

STRING.lower() returns a copy of STRING with all the letters in lower case.

text = 'the cAT in THE hat'
text.lower()
'the cat in the hat'

capitalize()#

STRING.capitalize() returns a copy of STRING in which the first character is upper case and all the other letters are lower case.

text = 'the cAT in THE hat'
text.capitalize()
'The cat in the hat'

title()#

STRING.title() returns a copy of STRING in which each word starts with an upper case letter, and all the other letters are lower case.

text = 'the cAT in THE hat'
text.title()
'The Cat In The Hat'

Be careful: for title(), a “word” starts after each character that is not a letter, also after an apostrophe. This is correct for a name, but not for don't:

print("o'brien".title())
print("don't stop".title())
O'Brien
Don'T Stop

swapcase()#

STRING.swapcase() returns a copy of STRING in which each upper case letter is lower case, and each lower case letter is upper case.

text = 'the cAT in THE hat'
text.swapcase()
'THE Cat IN the HAT'

Using the methods on text that a user types#

Here is a function that asks for a name (with input, Chapter 5), and then greets the user with the name in title case:

def greet():
    name = input('What is your name? ')
    print('Hello, ' + name.title() + '!')

When you run the next cell in Colab, a box opens under the cell. Type a name in it, then push Enter. (On the website, the page cannot wait for you to type, so a pretend user typed the names that you see.)

greet()
What is your name? mary smith
Hello, Mary Smith!

Another user types the name with Caps Lock on. The result is the same:

greet()
What is your name? JOHN DOE
Hello, John Doe!

Here is a function that asks a yes-or-no question. It compares the answer with 'yes' and 'no', after it changes the answer to lower case:

def likes_python():
    answer = input('Do you like Python? Type yes or no: ')
    if answer.lower() == 'yes':
        print('Great! Me too.')
    elif answer.lower() == 'no':
        print('Maybe you will like it at the end of this course.')
    else:
        print('Please type yes or no.')
likes_python()
Do you like Python? Type yes or no: YES
Great! Me too.
likes_python()
Do you like Python? Type yes or no: Yes
Great! Me too.
likes_python()
Do you like Python? Type yes or no: no
Maybe you will like it at the end of this course.

Without lower(), the comparison answer == 'yes' is False when the user types YES or Yes, because 'YES' and 'yes' are different strings:

'YES' == 'yes'
False

The section on strip() below shows one more problem with what users type, and how to fix it.

Methods that take arguments: startswith() and endswith()#

The methods above take no arguments. Many string methods take arguments, in the parentheses, as functions do. Chapter 8 uses two of them: startswith and endswith.

Optional arguments. Some arguments are optional: you can give them, or leave them out. You saw this before: input works with a prompt or without one (Chapter 5), and open works with the mode 'w' or without it (Chapter 8). When you leave out an optional argument, the method uses a default value.

On this page, the general form of a method shows each correct way to call it. The descriptions tell which arguments are optional, and what their default values are.

Quick summary. Each line shows a call, and the value that it returns. The details of each method are below.

date                          '2026-10-21'
date.startswith('2026')       True
date.startswith('10', 5)      True
date.startswith('10', 5, 7)   True
date.endswith('21')           True
date.endswith('21', 8)        True
date.endswith('10', 0, 7)     True

Details: startswith and endswith#

To hide or show the details of each method, click the arrow next to this heading.

startswith()#

STRING.startswith(PREFIX)
STRING.startswith(PREFIX, START)
STRING.startswith(PREFIX, START, END)

startswith returns True if STRING starts with PREFIX, and False if it does not.

  • PREFIX: the characters to look for at the start.

  • START (optional): the index where the check starts. The default is 0, the start of the string.

  • END (optional): the index where the check stops. As in a slice, the character at index END is not part of the check. The default is the end of the string.

With START and END, startswith checks the slice STRING[START:END]. For example, date.startswith('10', 5, 7) gives the same result as date[5:7].startswith('10').

The examples use a date, written year-month-day. Only PREFIX: does the date start with '2026'?

date = '2026-10-21'
date.startswith('2026')
True

PREFIX and START: the month starts at index 5. Is the month October ('10')?

date = '2026-10-21'
date.startswith('10', 5)
True

PREFIX, START and END: check only the characters at indexes 5 and 6 (the month):

date = '2026-10-21'
date.startswith('10', 5, 7)
True

endswith()#

STRING.endswith(SUFFIX)
STRING.endswith(SUFFIX, START)
STRING.endswith(SUFFIX, START, END)

endswith returns True if STRING ends with SUFFIX, and False if it does not.

  • SUFFIX: the characters to look for at the end.

  • START (optional): the index where the check starts. The default is 0, the start of the string.

  • END (optional): the index where the check stops. As in a slice, the character at index END is not part of the check. The default is the end of the string.

With START and END, endswith checks the slice STRING[START:END]. For example, date.endswith('10', 0, 7) gives the same result as date[0:7].endswith('10').

Only SUFFIX: is it the 21st day of the month?

date = '2026-10-21'
date.endswith('21')
True

SUFFIX and START: check from index 8 (the day) to the end:

date = '2026-10-21'
date.endswith('21', 8)
True

SUFFIX, START and END: does the part from index 0 to index 6 (the year and the month) end with '10'?

date = '2026-10-21'
date.endswith('10', 0, 7)
True

The comparison is case sensitive: 'A' and 'a' are different characters. To ignore case, call lower() first. Then call endswith on the result: Python calls the methods from left to right.

filename = 'Vacation.JPG'
print(filename.endswith('.jpg'))
print(filename.lower().endswith('.jpg'))
False
True

Two rules for optional arguments#

  1. Give the arguments in the order of the general form. To give END, you must also give START.

  2. For most string methods, you cannot give arguments as keyword arguments (Chapter 4). Python shows a TypeError:


date = '2026-10-21'
date.startswith('10', start=5)
TypeError: str.startswith() takes no keyword arguments

Counting: count()#

count returns the number of times that a substring is in a string.

Quick summary. Each line shows a call, and the value that it returns. The details of each method are below.

'banana'.count('a')         3
'banana'.count('an')        2
'banana'.count('a', 2)      2
'banana'.count('a', 2, 4)   1

Details: count#

To hide or show the details of each method, click the arrow next to this heading.

count()#

STRING.count(SUB)
STRING.count(SUB, START)
STRING.count(SUB, START, END)

count returns the number of times that SUB is in STRING. (SUB means substring: a part of a string.) Chapter 8 uses count to count the times that the name “Jonathan” is in Dracula.

  • SUB: the string to count.

  • START, END (optional): count only in the slice STRING[START:END], as for startswith. The defaults are the start and the end of the string.

Only SUB:

'banana'.count('a')
3

SUB can have more than one character:

'banana'.count('an')
2

count does not count matches that overlap. 'ana' is in 'banana' at index 1 and at index 3, but these two matches share the a at index 3, so count finds only the first one:

'banana'.count('ana')
1

SUB and START: count from index 2 to the end ('nana'):

'banana'.count('a', 2)
2

SUB, START and END: count from index 2 up to index 4, without index 4 ('na'):

'banana'.count('a', 2, 4)
1

count is case sensitive. To count upper and lower case letters together, call lower() first:

print('Banana'.count('b'))
print('Banana'.lower().count('b'))
0
1

Replacing and removing characters#

The methods in this section return a copy of the string in which some characters are replaced or removed.

Quick summary. Each line shows a call, and the value that it returns. The details of each method are below.

'banana'.replace('a', 'o')               'bonono'
'banana'.replace('a', 'o', 2)            'bonona'
'   hi there   '.strip()                 'hi there'
'...Wait!!!'.strip('.!')                 'Wait'
'   hi   '.lstrip()                      'hi   '
'   hi   '.rstrip()                      '   hi'
'www.example.com'.removeprefix('www.')   'example.com'
'www.example.com'.removesuffix('.com')   'www.example'

Details: replace, strip, lstrip, rstrip, removeprefix and removesuffix#

To hide or show the details of each method, click the arrow next to this heading.

replace()#

STRING.replace(OLD, NEW)
STRING.replace(OLD, NEW, COUNT)

replace returns a copy of STRING in which OLD is replaced with NEW. Chapter 8 uses it to change the name “Jonathan” to “Thomas”.

  • OLD: the string to find.

  • NEW: the string to put in its place.

  • COUNT (optional): the largest number of replacements. The default: replace all of them.

Only OLD and NEW: replace each 'a':

'banana'.replace('a', 'o')
'bonono'

OLD, NEW and COUNT: replace only the first two:

'banana'.replace('a', 'o', 2)
'bonona'

To remove characters, replace them with the empty string, '':

'555-123-4567'.replace('-', '')
'5551234567'

replace is case sensitive. Here, nothing changes, because the string has an upper case B only:

'Banana'.replace('b', 'c')
'Banana'

strip()#

STRING.strip()
STRING.strip(CHARS)

strip returns a copy of STRING without the whitespace at its start and at its end. Whitespace is the characters that you do not see: spaces, tabs, and newlines ('\n'). Whitespace in the middle of the string stays.

  • CHARS (optional): the characters to remove, in place of whitespace. CHARS is a set of characters, not a word: strip removes each of these characters, in any order, from the two ends.

Chapter 8 uses line.strip() to remove the newline at the end of each line of a file.

Without CHARS, strip removes the spaces at the two ends, but not the space in the middle:

'   hello world   '.strip()
'hello world'

It also removes newlines:

'hello\n'.strip()
'hello'

With CHARS: remove the dots and the exclamation marks at the two ends:

'...Wait!!!'.strip('.!')
'Wait'

Be careful: CHARS is a set of characters. strip('ab') removes each a and each b at the two ends, until it finds a different character:

'banana'.strip('ab')
'nan'

Users often type a space before or after their answer. They do not see it, but the program does. Here, the user typed a space before yes, so likes_python (from the section on user input) does not understand the answer:

def likes_python():
    answer = input('Do you like Python? Type yes or no: ')
    if answer.lower() == 'yes':
        print('Great! Me too.')
    elif answer.lower() == 'no':
        print('Maybe you will like it at the end of this course.')
    else:
        print('Please type yes or no.')

likes_python()
Do you like Python? Type yes or no:  yes
Please type yes or no.

The fix is to call strip() and then lower() on the answer. Python calls the methods from left to right: strip() returns a new string, then lower() is called on that string.

def likes_python():
    answer = input('Do you like Python? Type yes or no: ')
    answer = answer.strip().lower()
    if answer == 'yes':
        print('Great! Me too.')
    elif answer == 'no':
        print('Maybe you will like it at the end of this course.')
    else:
        print('Please type yes or no.')
likes_python()
Do you like Python? Type yes or no:   YES  
Great! Me too.

lstrip() and rstrip()#

STRING.lstrip()
STRING.lstrip(CHARS)

STRING.rstrip()
STRING.rstrip(CHARS)

lstrip and rstrip are like strip, but they remove characters from one end only: lstrip from the left end (the start), and rstrip from the right end (the end).

  • CHARS (optional): the characters to remove, as for strip. The default is whitespace.

'   hello   '.lstrip()
'hello   '
'   hello   '.rstrip()
'   hello'

For example, a line of a file can start with spaces that you want to keep. rstrip('\n') removes only the newline at the end:

'    indented line\n'.rstrip('\n')
'    indented line'

With CHARS: remove the dollar signs at the start only:

'$$$42.50$'.lstrip('$')
'42.50$'

removeprefix() and removesuffix()#

STRING.removeprefix(PREFIX)
STRING.removesuffix(SUFFIX)

removeprefix returns a copy of STRING without PREFIX at its start. removesuffix returns a copy of STRING without SUFFIX at its end. If STRING does not start with PREFIX (or end with SUFFIX), they return STRING unchanged.

  • PREFIX, SUFFIX: the exact string to remove. Unlike CHARS for strip, it is a string, not a set of characters, and it is removed only once.

'www.example.com'.removeprefix('www.')
'example.com'
'www.example.com'.removesuffix('.com')
'www.example'

If the string does not start with PREFIX, nothing changes:

'Smith'.removeprefix('Mr. ')
'Smith'

Compare with strip. strip('w.com') removes each of the characters w, ., c, o and m from the two ends, so it also removes the .com:

'www.example.com'.strip('w.com')
'example'

And compare with lstrip. lstrip('a') removes all the a characters at the start, but removeprefix('a') removes only one:

print('aaab'.lstrip('a'))
print('aaab'.removeprefix('a'))
b
aab

Lining up text: center, ljust and rjust#

These methods add characters to a string, until the string has a given length. They are useful to show text in columns, as in a table.

Quick summary. Each line shows a call, and the value that it returns. The details of each method are below.

'Python'.center(12)        '   Python   '
'Python'.center(12, '*')   '***Python***'
'Python'.ljust(12, '.')    'Python......'
'Python'.rjust(12, '.')    '......Python'

Details: center, ljust and rjust#

To hide or show the details of each method, click the arrow next to this heading.

center()#

STRING.center(WIDTH)
STRING.center(WIDTH, FILLCHAR)

center returns a copy of STRING in the middle of a new string of length WIDTH, with characters added at the two ends.

  • WIDTH: the length of the new string. If STRING has WIDTH characters or more, center returns STRING unchanged: it never makes a string shorter.

  • FILLCHAR (optional): the character to add. It must be exactly one character. The default is a space, ' '.

'Python'.center(20)
'       Python       '
'Python'.center(20, '*')
'*******Python*******'

WIDTH is shorter than the string, so the string does not change:

'Python'.center(3)
'Python'

FILLCHAR must be one character:


'Python'.center(20, '*-')
TypeError: The fill character must be exactly one character long

ljust() and rjust()#

STRING.ljust(WIDTH)
STRING.ljust(WIDTH, FILLCHAR)

STRING.rjust(WIDTH)
STRING.rjust(WIDTH, FILLCHAR)

ljust returns a copy of STRING, left justified in a new string of length WIDTH: STRING is at the left, and the characters are added at the right. rjust is the opposite (right justified): STRING is at the right, and the characters are added at the left.

  • WIDTH, FILLCHAR: the same as for center.

'Python'.ljust(10, '.')
'Python....'
'Python'.rjust(10, '.')
'....Python'

Here, ljust and rjust line up the items and the prices of a menu. The function print_row makes each item 12 characters long and each price 7 characters long, so the columns line up. str (Chapter 2) changes the price into a string, because rjust is a string method.

def print_row(item, price):
    print(item.ljust(12, '.') + str(price).rjust(7))

print('MENU'.center(19, '='))
print_row('Coffee', 2.5)
print_row('Bagel', 3.25)
print_row('Orange juice', 4)
========MENU=======
Coffee......    2.5
Bagel.......   3.25
Orange juice      4

With input, the program can line up text that the user types. This function shows the user’s name in a banner:

def banner():
    name = input('What is your name? ')
    print('*' * 30)
    print(name.strip().upper().center(30))
    print('*' * 30)
banner()
What is your name? mary smith
******************************
          MARY SMITH          
******************************

Testing the characters: isdigit(), isalpha() and other methods#

The methods in this section test the characters of a string. Each one returns True or False. None of them takes an argument.

For the empty string '', each of these methods returns False.

Quick summary. Each line shows a call, and the value that it returns. The details of each method are below.

'2026'.isdigit()          True
'3.5'.isdigit()           False
'Hello'.isalpha()         True
'Hello world'.isalpha()   False
'R2D2'.isalnum()          True
'   '.isspace()           True
'HELLO!'.isupper()        True
'hello 123'.islower()     True
'The Cat'.istitle()       True

Details: isdigit, isalpha, isalnum, isspace, isupper, islower and istitle#

To hide or show the details of each method, click the arrow next to this heading.

These methods are useful to check what a user typed, before the program uses it. In Chapter 5, int(speed) causes a ValueError if the user does not type a number. isdigit can check the text first:

def ask_age():
    age = input('How old are you? ')
    if age.isdigit():
        print('Next year, you will be', int(age) + 1)
    else:
        print(age, 'is not a whole number.')
ask_age()
How old are you? 19
Next year, you will be 20
ask_age()
How old are you? nineteen
nineteen is not a whole number.

isdigit()#

STRING.isdigit() returns True if each character of STRING is a digit (0 to 9).

A minus sign, a decimal point and a space are not digits.

print('2026'.isdigit())
print('-5'.isdigit())
print('3.5'.isdigit())
print(' 19'.isdigit())
True
False
False
False

isalpha()#

STRING.isalpha() returns True if each character of STRING is a letter.

A space is not a letter, so a string with two words is not alphabetic.

print('Hello'.isalpha())
print('Hello world'.isalpha())
print('R2D2'.isalpha())
True
False
False

isalnum()#

STRING.isalnum() returns True if each character of STRING is a letter or a digit (alphanumeric).

print('R2D2'.isalnum())
print('R2-D2'.isalnum())
True
False

isspace()#

STRING.isspace() returns True if each character of STRING is whitespace (spaces, tabs, newlines).

For example, use it to find the empty lines of a file. A line that looks empty usually has a newline.

print('   '.isspace())
print('\n'.isspace())
print(' a '.isspace())
True
True
False

isupper() and islower()#

STRING.isupper() returns True if STRING has at least one letter, and all its letters are upper case. STRING.islower() returns True if STRING has at least one letter, and all its letters are lower case. Characters that are not letters do not matter.

print('HELLO, WORLD!'.isupper())
print('Hello'.isupper())
print('hello 123'.islower())
print('123'.islower())
True
False
True
False

istitle()#

STRING.istitle() returns True if STRING has at least one letter, and it is in title case: each word starts with an upper case letter, and the other letters are lower case. It is the test for the result of title().

print('The Cat In The Hat'.istitle())
print('The cat in the hat'.istitle())
True
False

Finding where a substring is: find(), rfind(), index() and rindex()#

The in operator (Chapter 8) tells you if a string contains a substring. The methods in this section tell you where it is: they return its index. Why do you need the index? With the index, you can slice the string (Chapter 8) at that place, to get the part before it or the part after it.

index and rindex are like find and rfind, but when the substring is not there, they cause a ValueError in place of returning -1.

Quick summary. Each line shows a call, and the value that it returns. The details of each method are below.

'one fish two fish'.find('fish')     4
'one fish two fish'.rfind('fish')    13
'one fish two fish'.find('cat')      -1
'one fish two fish'.rfind('cat')     -1
'one fish two fish'.index('fish')    4
'one fish two fish'.rindex('fish')   13

Details: find, rfind, index and rindex#

To hide or show the details of each method, click the arrow next to this heading.

find()#

STRING.find(SUB)
STRING.find(SUB, START)
STRING.find(SUB, START, END)

find returns the index of the first time that SUB is in STRING (the index of the first character of SUB). If SUB is not in STRING, find returns -1.

  • SUB: the string to find.

  • START, END (optional): look only in the slice STRING[START:END], as for count. The index that find returns is an index of STRING, not of the slice.

For example, an email address has a user name before the @ and a domain after it. find gives the index of the @:

email = 'mary.smith@example.com'
at = email.find('@')
at
10

Slices with this index give the two parts:

email = 'mary.smith@example.com'
at = email.find('@')
print(email[:at])
print(email[at + 1:])
mary.smith
example.com

With START, find can find the second time that a substring is in a string. First, find the first time. Then, look again, from the next index:

text = 'one fish two fish red fish'
first = text.find('fish')
second = text.find('fish', first + 1)
print(first, second)
4 13

With START and END, look only from index 0 up to index 7 ('one fis'). The word fish is not complete there, so find returns -1:

text = 'one fish two fish red fish'
text.find('fish', 0, 7)
-1

Always check for -1. -1 is a correct index (the last character), so a slice with it does not cause an error. It gives a wrong result, and you do not see the problem. Here, the address has no @, and the slice removes the last letter:

email = 'marysmith'
at = email.find('@')
email[:at]
'marysmit'

This program asks for an email address and checks for -1 before it slices:

def ask_email():
    email = input('What is your email address? ')
    at = email.find('@')
    if at == -1:
        print('That is not an email address: it has no @.')
    else:
        print('User name:', email[:at])
        print('Domain:', email[at + 1:])
ask_email()
What is your email address? mary.smith@example.com
User name: mary.smith
Domain: example.com
ask_email()
What is your email address? mary.smith.example.com
That is not an email address: it has no @.

rfind()#

STRING.rfind(SUB)
STRING.rfind(SUB, START)
STRING.rfind(SUB, START, END)

rfind is like find, but it returns the index of the last time that SUB is in STRING (r is for right: it searches from the right end). If SUB is not in STRING, rfind returns -1.

  • SUB, START, END: the same as for find.

For example, the extension of a file name is the part after the last dot. A file name can have more than one dot, so find gives the wrong dot:

filename = 'my.vacation.photo.jpg'
print(filename.find('.'))
print(filename.rfind('.'))
2
17
filename = 'my.vacation.photo.jpg'
filename[filename.rfind('.') + 1:]
'jpg'

In the same way, the file name in a path is the part after the last /:

path = 'C:/Users/mary/Documents/notes.txt'
path[path.rfind('/') + 1:]
'notes.txt'

index() and rindex()#

STRING.index(SUB)
STRING.index(SUB, START)
STRING.index(SUB, START, END)

STRING.rindex(SUB)
STRING.rindex(SUB, START)
STRING.rindex(SUB, START, END)

index is like find, and rindex is like rfind, with one difference: if SUB is not in STRING, they cause a ValueError, in place of returning -1.

  • SUB, START, END: the same as for find.

'mary.smith@example.com'.index('@')
10

'marysmith'.index('@')
ValueError: substring not found

Which one do you use?

  • Use find (or rfind) when it is normal that the substring is not there, for example in text that a user types. Check for -1, as ask_email does.

  • Use index (or rindex) when the substring must be there. If it is not there, there is a bug, and the error tells you about it at once. With find, the -1 can give a wrong result that you do not see.

Summary: the methods on this page#

In the general forms, the brackets [ ] show the optional arguments. (Do not type the brackets.) For example, count(SUB[, START[, END]]) means count(SUB), count(SUB, START) or count(SUB, START, END). The official reference uses the same notation.

Method

General form

What it returns

upper()

STRING.upper()

all letters upper case

lower()

STRING.lower()

all letters lower case

capitalize()

STRING.capitalize()

first character upper case, the other letters lower case

title()

STRING.title()

each word starts with an upper case letter

swapcase()

STRING.swapcase()

upper case to lower case, lower case to upper case

startswith()

STRING.startswith(PREFIX[, START[, END]])

True if STRING starts with PREFIX

endswith()

STRING.endswith(SUFFIX[, START[, END]])

True if STRING ends with SUFFIX

count()

STRING.count(SUB[, START[, END]])

how many times SUB is in STRING (no overlaps)

replace()

STRING.replace(OLD, NEW[, COUNT])

replace OLD with NEW (at most COUNT times)

strip()

STRING.strip([CHARS])

remove whitespace (or CHARS) at the two ends

lstrip()

STRING.lstrip([CHARS])

remove whitespace (or CHARS) at the start

rstrip()

STRING.rstrip([CHARS])

remove whitespace (or CHARS) at the end

removeprefix()

STRING.removeprefix(PREFIX)

remove PREFIX once, if STRING starts with it

removesuffix()

STRING.removesuffix(SUFFIX)

remove SUFFIX once, if STRING ends with it

center()

STRING.center(WIDTH[, FILLCHAR])

STRING in the middle of a string of length WIDTH

ljust()

STRING.ljust(WIDTH[, FILLCHAR])

STRING at the left of a string of length WIDTH

rjust()

STRING.rjust(WIDTH[, FILLCHAR])

STRING at the right of a string of length WIDTH

isdigit()

STRING.isdigit()

True if all characters are digits

isalpha()

STRING.isalpha()

True if all characters are letters

isalnum()

STRING.isalnum()

True if all characters are letters or digits

isspace()

STRING.isspace()

True if all characters are whitespace

isupper()

STRING.isupper()

True if all letters are upper case

islower()

STRING.islower()

True if all letters are lower case

istitle()

STRING.istitle()

True if each word starts with an upper case letter

find()

STRING.find(SUB[, START[, END]])

index of the first SUB, or -1

rfind()

STRING.rfind(SUB[, START[, END]])

index of the last SUB, or -1

index()

STRING.index(SUB[, START[, END]])

like find, but a ValueError if SUB is not there

rindex()

STRING.rindex(SUB[, START[, END]])

like rfind, but a ValueError if SUB is not there

Practice questions#

Question 1 (easy): what is displayed?#

Predict what this code displays. Then run the cell to check (on the website, click Show code cell output).

text = 'hello WORLD'
print(text.capitalize())
print(text.title())
print(text.swapcase())
print(text)

Hide code cell output

Hello world
Hello World
HELLO world
hello WORLD

Question 2 (easy): what is displayed?#

Predict what this code displays. Then run the cell to check (on the website, click Show code cell output).

print('Mississippi'.count('s'))
print('Mississippi'.count('ss'))
print('Mississippi'.count('issi'))
print('Mississippi'.count('s', 4))

Hide code cell output

4
2
1
2

Question 3 (medium): what is displayed?#

Predict what this code displays. Then run the cell to check (on the website, click Show code cell output).

word = 'banana'
print(word.strip('an'))
print(word.removesuffix('an'))
print(word.removesuffix('ana'))
print(word.rstrip('a'))

Hide code cell output

b
banana
ban
banan

Question 4 (medium): which calls cause an error?#

Which of these calls cause an error? For each call that works, what does it return? Try each call in a code cell to check.

  1. 'banana'.find('x')

  2. 'banana'.index('x')

  3. 'banana'.count('a', start=2)

  4. 'banana'.center(10, '-')

  5. 'banana'.center(10, '--')

  6. 'banana'.startswith('an', 1)

Question 5 (medium): write a function#

Write a function called is_yes that takes a string answer (text that a user typed), and returns True if the answer is yes or y. Upper and lower case do not matter, and spaces before and after the answer do not matter. For example, is_yes('  YES ') and is_yes('Y') return True, and is_yes('no') and is_yes('yes please') return False.

Start from this header (replace ... with the body):

def is_yes(answer):
    ...

Question 6 (hard): write a function#

Write a function called domain that takes an email address and returns the part after the @. If the address has no @, the function returns the empty string, ''. For example, domain('mary@example.com') returns 'example.com', and domain('mary') returns ''.

Start from this header (replace ... with the body):

def domain(email):
    ...

Question 7 (hard): write a function#

Write a function called extension that takes a file name and returns its extension (the part after the last dot), in lower case. If the file name has no dot, the function returns the empty string, ''. For example, extension('photo.JPG') returns 'jpg', extension('my.vacation.photo.png') returns 'png', and extension('README') returns ''.

Start from this header (replace ... with the body):

def extension(filename):
    ...

Credits#

Additions by Prof. Y. Rosenthal, for Think Python: 3rd Edition by Allen B. Downey. Text license: Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International