Python Strings

Work with text in Python: indexing, slicing, string methods, searching and formatting output.

Lesson 10 of 107Beginner19 min read

Almost every program works with text. Names, email addresses, messages, file names and web pages are all strings: sequences of characters stored in order. In the variables lesson you created strings and joined them with f-strings. Now you'll learn to take them apart, clean them up and search inside them.

Python treats a string a little like a list of characters. You can ask for the first character, the last three, or everything between two positions. On top of that, every string comes with dozens of built-in methods: small functions such as upper(), strip() and replace() that return a changed copy of the text.

By the end of this lesson you'll be able to tidy messy input, pull pieces out of text and split sentences into words.

Writing strings and escape characters

You can write a string with single quotes or double quotes. They mean exactly the same thing, so choose whichever avoids clashes with the text inside:

Python
greeting = "It's a lovely day"
quote = 'She said "hello" and left'

For text that spans several lines, use triple quotes: """ or '''. The line breaks are kept exactly as you type them.

A backslash starts an escape sequence, a way of writing characters that are hard to type directly:

EscapeMeaning
\nNew line
\tTab
\" or \'A quote inside a string using the same quotes
\\A real backslash

Windows file paths contain backslashes, so they often cause surprises. Write them as raw strings, with an r before the quote, and Python leaves every backslash alone: r"C:\Users\maya\notes.txt".

Joining, repeating and looping over strings

The + operator joins two strings into a new one, and * repeats a string a whole number of times:

Python
first = "Ada"
last = "Lovelace"
print(first + " " + last)   # Ada Lovelace
print("-" * 12)             # ------------

Both sides of + must be strings. To include a number, use an f-string or convert it with str().

Because a string is a sequence, a for loop visits it one character at a time. This is the simplest way to inspect or count characters:

Python
vowels = 0
for letter in "programming":
    if letter in "aeiou":
        vowels += 1
print(vowels)   # 3

Indexing and slicing

Each character in a string has a position, starting at 0:

Python
word = "Python"
print(word[0])    # P
print(word[-1])   # n  (negative indexes count from the end)
print(word[0:3])  # Pyt
print(word[2:])   # thon
print(word[::-1]) # nohtyP

A slice has the form [start:stop:step]. The start is included and the stop is not, just as with range(). Leave out the start to begin at the front, leave out the stop to run to the end, and use a step of -1 to walk backwards, which is a quick way to reverse a string.

len(word) tells you how many characters a string has. Strings are immutable: you can read characters by index, but you can't change them in place. word[0] = "J" raises a TypeError. Instead you build a new string, for example "J" + word[1:].

Common string methods

Methods are called with a dot after the string. Because strings can't change, each method returns a new string and leaves the original untouched.

MethodWhat it returns
s.upper() / s.lower()All capitals / all lower case
s.title()Each Word Capitalised
s.strip()Spaces removed from both ends
s.replace("a", "b")Every "a" replaced with "b"
s.startswith("Mr")True or False
s.count("e")How many times "e" appears
s.split(",")A list of pieces, cut at each comma
", ".join(items)One string built from a list

split() with no argument splits on any run of spaces, tabs or new lines, which makes it ideal for breaking a sentence into words. join() does the opposite and is called on the separator, not on the list.

Searching inside strings

To check whether some text appears anywhere in a string, use the in operator. It returns True or False and reads like plain English:

Python
email = "maya@example.com"
if "@" in email:
    print("Looks like an email")

If you need the position of the match, use find(). It returns the index of the first match, or -1 if there isn't one. index() does the same but raises an error when nothing is found. Searches are case-sensitive, so a common trick is to compare lower-case versions: "python" in text.lower().

Comparing and testing strings

== compares strings character by character, and the comparison is case-sensitive: "Paris" == "paris" is False. For case-insensitive checks, compare lower-case copies, or use casefold(), which also handles special characters such as the German "ß".

< and > compare strings alphabetically by character code, so every capital letter sorts before every lower-case one: "Zebra" < "apple" is True. Lower-case both sides when you sort names for people to read.

A family of is... methods tests what a string contains, which is useful before converting input:

MethodTrue when the string...
s.isdigit()contains only digits, such as "2024"
s.isalpha()contains only letters
s.isalnum()contains only letters and digits
s.isspace()contains only whitespace

Note that "-5".isdigit() and "3.5".isdigit() are both False, because - and . are not digits. To accept those, try the conversion inside try/except, which you'll learn in the error handling lesson.

Python Strings Syntax

String operations

text = "Hello, world"
text[0]              # first character
text[-1]             # last character
text[0:5]            # slice
len(text)            # length
text.lower()         # new lower-case string
text.split(", ")     # list of parts
"-".join(["a", "b"]) # "a-b"
"world" in text      # True

Python Strings Summary

  • Strings can use single, double or triple quotes; \n and \t are escape sequences.
  • Indexes start at 0; negative indexes count from the end.
  • s[start:stop:step] slices a string; the stop position isn't included.
  • Strings are immutable, so methods return new strings.
  • split() breaks text into a list and join() builds a string from a list.
  • Use in to test whether text appears, and find() to get its position.

Python Strings Examples

Each example shows the code, the output it produces and what each part does.

Example 1

Tidying up a name

Python
raw = "   ada LOVELACE  "

clean = raw.strip().title()
print(f"[{clean}]")
print("Letters:", len(clean.replace(" ", "")))
print("Initials:", clean[0] + clean.split()[1][0])
Output
[Ada Lovelace]
Letters: 11
Initials: AL
Line-by-line explanation
  1. Line 3strip() removes the outer spaces, then title() capitalises each word.
  2. Line 4The square brackets in the output show that no spaces are left at the ends.
  3. Line 5Remove the inner space before counting the letters.
  4. Line 6The first letter of the whole name, plus the first letter of the second word.
Example 2

Slicing a date and a product code

Python
date = "2024-09-15"
year = date[:4]
month = date[5:7]
day = date[-2:]
print(f"Day {day}, month {month}, year {year}")

code = "SKU-48213-BLUE"
parts = code.split("-")
print(parts)
print("Colour:", parts[2].lower())
Output
Day 15, month 09, year 2024
['SKU', '48213', 'BLUE']
Colour: blue
Line-by-line explanation
  1. Lines 2 to 4Slices pick out fixed positions in the text.
  2. Line 8split("-") cuts the code at every dash and returns a list.
  3. Line 10Index 2 is the third piece, the colour.
Example 3

Counting words in a sentence

Python
sentence = "the quick brown fox jumps over the lazy dog"
words = sentence.split()

print("Words:", len(words))
print("Longest:", max(words, key=len))
print("'the' appears", sentence.count("the"), "times")
print(" ".join(word.capitalize() for word in words))
Output
Words: 9
Longest: quick
'the' appears 2 times
The Quick Brown Fox Jumps Over The Lazy Dog
Line-by-line explanation
  1. Line 2With no argument, split() breaks the text on spaces.
  2. Line 5key=len tells max() to compare the words by their length. "quick", "brown" and "jumps" all have five letters, and max() returns the first one it finds.
  3. Line 7join() glues the capitalised words back together with spaces.

Common Python Strings Mistakes

Trying to change a character in place

Don't
name = "jane"
name[0] = "J"
Do
name = "jane"
name = "J" + name[1:]

Strings are immutable, so the first version raises TypeError: 'str' object does not support item assignment.

Forgetting that methods return a new string

Don't
city = "  paris "
city.strip()
print(city)   # still "  paris "
Do
city = "  paris "
city = city.strip()
print(city)   # "paris"

Calling join on the list

Don't
words = ["red", "green", "blue"]
print(words.join(", "))
Do
words = ["red", "green", "blue"]
print(", ".join(words))

join() belongs to the separator string, so the list version raises an AttributeError.

Python Strings in Real Projects

Strings in real programs

Data analysts spend a lot of time cleaning text: trimming spaces and making capitals consistent so that "London" and "london " count as the same city. Command-line tools split each line of a log file to find errors.

Python Strings FAQ

How do I check if a string is empty in Python?

An empty string is falsy, so if not text: is the usual check. It is shorter than if text == "": or if len(text) == 0: and reads naturally. If the value might contain only spaces, strip it first: if not text.strip():.

How do I remove a character or word from a string?

Replace it with an empty string: "2024-09-15".replace("-", "") gives "20240915". To remove characters only from the ends, pass them to strip(): "$$42$$".strip("$") gives "42". The original string is unchanged, so assign the result to a variable.

How do I turn a string into a list of characters?

Call list() on it: list("cat") gives ['c', 'a', 't']. Use split() instead when you want words or pieces separated by a delimiter, and "".join(chars) to turn the list back into a single string.

Why are Python strings immutable?

Immutability makes strings safe to share: if two variables refer to the same text, neither can change it under the other. It also lets Python use strings as dictionary keys and reuse identical strings to save memory. When you need to change text, you create a new string from pieces of the old one.

What is the difference between find() and the in operator?

in answers yes or no: "@" in email is True or False. find() tells you where the match starts, returning the index or -1 when there is no match. Use in for checks and find() (or index()) when you need the position to slice the string.

Python Strings Exercises

Answer each one and check it instantly. If you get stuck, open the hint before the answer.

Fill in the blankseasy

Complete the code so it prints HELLO.

word = "hello"
print(word.())
Predict the outputeasy

What does this print?

s = "Python"
print(s[1:4])
Predict the outputmedium

What does this print?

tags = "html, css,  js"
print([t.strip() for t in tags.split(",")])
Fill in the blanksmedium

Complete the code so it prints a-b-c.

letters = ["a", "b", "c"]
print("".(letters))
Multiple choicemedium

What does "banana".find("x") return?

Python Strings Quiz

5 questions to check what you learned.

  1. What is the index of the first character in a Python string?

    • 1
    • -1
    • It depends on the string
    • 0
  2. Which method removes spaces from both ends of a string?

    • trim()
    • clean()
    • strip()
    • cut()
  3. What does "hello"[::-1] return?

    • "hello"
    • "olleh"
    • "h"
    • An error
  4. Why does s.upper() on its own not change s?

    • upper() only works inside print()
    • Strings are immutable, so upper() returns a new string
    • You must call it twice
    • upper() only changes the first letter
  5. What does "a,b,,c".split(",") return?

    • ['a', 'b', 'c']
    • ['a,b,,c']
    • ['a', 'b', '', 'c']
    • ['a', 'b', ',', 'c']