Skip to main content

4.1 - Working With Strings

A Python string is a sequence of characters. In Python, characters are simply strings of length one. Strings are used to store text-based data and are enclosed in either single quotes ('...') or double quotes ("...").

Strings are immutable, meaning once they are created, their contents cannot be changed. However, you can create new strings by manipulating existing ones through various operations like concatenation, slicing, and formatting.

4.1.1 - String Basics

Strings in Python are created by enclosing characters in quotes. Python treats single quotes and double quotes the same:

# Using double quotes
string1 = "Hello, Python!"

# Using single quotes
string2 = 'Hello, Python!'

4.1.2 - String Concatenation

Strings can be concatenated using the + operator:

first_name = "John"
last_name = "Doe"
full_name = first_name + " " + last_name

4.1.3 - Accessing String Characters

Characters in a string can be accessed using indexing and slicing:

s = "Python"
first_char = s[0] # 'P'
slice = s[1:4] # 'yth'

4.1.4 - String Methods

Python strings come with a variety of built-in methods. Here are some common ones:

  • .upper(): Converts all characters to uppercase.
  • .lower(): Converts all characters to lowercase.
  • .strip(): Removes whitespace from the beginning and end.
  • .replace(old, new): Replaces all occurrences of the old substring with the new substring.

Example:

s = " Hello, World! "
print(s.upper()) # " HELLO, WORLD! "
print(s.lower()) # " hello, world! "
print(s.strip()) # "Hello, World!"
print(s.replace("World", "Python")) # " Hello, Python! "

4.1.5 - String Formatting

4.1.5.1 - f-strings

Since Python 3.6, f-strings (formatted string literals) are the most common way to embed expressions inside a string. Prefix the string with f and place any expression inside curly braces:

name = "John"
age = 30
greeting = f"Hello, my name is {name} and I am {age} years old."

f-strings also support format specifiers after a colon, and the = debugging specifier that prints both the expression's source text and its value:

pi = 3.14159
print(f"{pi:.2f}") # "3.14"
print(f"{pi=}") # "pi=3.14159"

4.1.5.2 - PEP 701: Formalized f-string Grammar (Python 3.12)

Python 3.12 (PEP 701) lifted several long-standing restrictions on what can appear inside the {} of an f-string:

  • Quote reuse: the expression inside {} can now reuse the same quote character as the f-string itself.

    songs = ["Take me back to Eden", "Alkaline", "Ascensionism"]
    print(f"This is the playlist: {", ".join(songs)}")

    Before 3.12, ", " would have raised a SyntaxError and needed different quote characters to work.

  • Arbitrary nesting: because quotes can now be reused, f-strings can be nested inside f-strings without switching quote styles at every level.

  • Multiline expressions and comments: the expression inside {} can span multiple lines and contain # comments, just like any other Python expression:

    total = f"{
    100
    + 250 # shipping
    + 20 # tax
    }"
  • Backslashes: backslashes are now allowed directly inside the expression portion of an f-string, without needing a helper variable.

4.1.5.3 - Template Strings (PEP 750, Python 3.14)

Python 3.14 (PEP 750) introduces template strings, written with a t prefix instead of f. Unlike an f-string, a t-string doesn't immediately produce a str — it produces a string.templatelib.Template object that keeps the literal text and the interpolated values separate, so custom code can process them before they're combined (for example, to escape values safely before building HTML or SQL):

variety = "Stilton"
template = t"Try some {variety} cheese!"
print(type(template)) # <class 'string.templatelib.Template'>

for part in template:
print(part)
# 'Try some '
# Interpolation('Stilton', 'variety', None, '')
# ' cheese!'

Iterating over a Template yields plain strings for the static parts and Interpolation objects for the {...} parts, each exposing the evaluated value, the source expression text, an optional conversion, and an optional format spec. This makes it easy to write a function that decides how each part gets rendered:

from string.templatelib import Interpolation

def render_upper(template):
"""Render static text as-is and interpolated values uppercased."""
parts = []
for part in template:
if isinstance(part, Interpolation):
parts.append(str(part.value).upper())
else:
parts.append(part)
return "".join(parts)

print(render_upper(template)) # "Try some STILTON cheese!"

4.1.6 - Advanced String Methods

  • .startswith(substring): Checks if the string starts with the given substring.
  • .endswith(substring): Checks if the string ends with the given substring.
  • .split(separator): Splits the string into a list, using the separator string.

Example:

s = "hello,world"
print(s.startswith("hello")) # True
print(s.endswith("world")) # True
print(s.split(",")) # ['hello', 'world']

4.1.7 - Working with Multiline Strings

Multiline strings can be created using triple quotes:

multi_line_string = """Line 1
Line 2
Line 3"""

4.1.8 - String Interpolation with .format()

Before the advent of f-strings, .format() was widely used for string interpolation:

greeting = "Hello, {name}. You are {age}.".format(name="Alice", age=42)

4.1.9 - Finding Substrings

  • .find(substring): Returns the lowest index of the substring if found, else -1.
  • .rfind(substring): Returns the highest index of the substring.

Example:

s = "Hello, world!"
print(s.find("world")) # 7
print(s.rfind("o")) # 8

4.1.10 - Checking String Content

  • .isdigit(): Returns True if all characters are digits.
  • .isalpha(): Returns True if all characters are alphabetic.
  • .isalnum(): Returns True if all characters are alphanumeric.

Example:

print("123".isdigit()) # True
print("abc".isalpha()) # True
print("abc123".isalnum()) # True

4.1.11 - Changing Case

  • .capitalize(): Capitalizes the first letter of the string.
  • .title(): Capitalizes the first letter of each word.

Example:

s = "hello world"
print(s.capitalize()) # "Hello world"
print(s.title()) # "Hello World"

4.1.12 - Joining and Splitting Strings

  • .join(iterable): Concatenates a series of strings from an iterable, separated by the string.

Example:

words = ["Hello", "world"]
print(" ".join(words)) # "Hello world"

4.1.13 - String Length

  • len(string): Returns the number of characters in the string.

Example:

print(len("Hello")) # 5

4.1.14 - Counting Substrings

  • .count(substring): Returns the number of occurrences of the substring.

Example:

s = "Hello, Hello, Hello"
print(s.count("Hello")) # 3

4.1.15 - Reversing a String

While not a direct string method, a common way to reverse a string is using slicing:

s = "Hello"
reversed_s = s[::-1]

4.1.16 - Checking for Whitespace, Upper, and Lower Case

  • .isspace(): Checks if all characters in the string are whitespace.
  • .isupper(): Checks if all characters are uppercase.
  • .islower(): Checks if all characters are lowercase.

Example:

print(" \t\n".isspace()) # True
print("ABC".isupper()) # True
print("abc".islower()) # True

4.1.17 - String Encoding and Decoding

  • .encode(encoding): Encodes the string into the specified encoding.
  • .decode(encoding): Decodes the string from the specified encoding.

Example:

s = "Hello, world!"
encoded_s = s.encode("utf-8")
decoded_s = encoded_s.decode("utf-8")

4.1.18 - Testing String Prefixes and Suffixes

  • .startswith(prefix[, start[, end]]): Returns True if the string starts with the specified prefix.
  • .endswith(suffix[, start[, end]]): Returns True if the string ends with the specified suffix.

Example:

print("Python".startswith("Py")) # True
print("Python".endswith("on")) # True

4.1.19 - Stripping Characters from a String

  • .lstrip([chars]): Removes leading characters (or whitespace if no characters are specified).
  • .rstrip([chars]): Removes trailing characters (or whitespace if no characters are specified).

Example:

s = " Hello, world! "
print(s.lstrip()) # "Hello, world! "
print(s.rstrip()) # " Hello, world!"

4.1.20 - String Partitioning

  • .partition(separator): Splits the string at the first occurrence of the separator, returning a 3-tuple.
  • .rpartition(separator): Splits the string at the last occurrence of the separator.

Example:

print("Hello, world!".partition(" ")) # ('Hello,', ' ', 'world!')
print("Hello, world!".rpartition(" ")) # ('Hello,', ' ', 'world!')

4.1.21 - Checking String Properties

  • .isidentifier(): Checks if the string is a valid identifier.
  • .istitle(): Checks if the string is titled correctly (each word starts with an uppercase letter).

Example:

print("variable_name".isidentifier()) # True
print("Hello World".istitle()) # True

4.1.22 - Summary Table of String Methods with Examples

MethodDescriptionExample
upper()Converts to uppercase."hello".upper()"HELLO"
lower()Converts to lowercase."HELLO".lower()"hello"
strip()Removes whitespace at both ends." hello ".strip()"hello"
replace(old, new)Replaces occurrences of a substring."hello".replace("e", "a")"hallo"
startswith(sub)Checks if the string starts with the substring."hello".startswith("he")True
endswith(sub)Checks if the string ends with the substring."hello".endswith("lo")True
split(separator)Splits the string into a list."a,b,c".split(",")["a", "b", "c"]
f'{variable}'Used for string formatting.name = "John"; f"Hello {name}""Hello John"
format()String interpolation with placeholders."Hello, {0}".format("world")"Hello, world"
find(sub)Finds the lowest index of the substring."hello".find("l")2
rfind(sub)Finds the highest index of the substring."hello".find("l")3
isdigit()Checks if the string contains only digits."123".isdigit()True
isalpha()Checks if the string contains only alphabetic characters."abc".isalpha()True
isalnum()Checks if the string contains only alphanumeric characters."abc123".isalnum()True
capitalize()Capitalizes the first letter of the string."hello".capitalize()"Hello"
title()Capitalizes the first letter of each word."hello world".title()"Hello World"
join(iterable)Joins elements of an iterable into a string." ".join(["Hello", "world"])"Hello world"
len(string)Returns the length of the string.len("Hello")5
count(substring)Counts occurrences of a substring."Hello Hello".count("Hello")2
s[::-1]Reverses the string."hello"[::-1]"olleh"
isspace()Checks for all whitespace." \t\n".isspace()True
isupper()Checks if all characters are uppercase."ABC".isupper()True
islower()Checks if all characters are lowercase."abc".islower()True
encode(encoding)Encodes the string."Hello".encode("utf-8")
decode(encoding)Decodes the string.b"Hello".decode("utf-8")
lstrip([chars])Removes leading characters or whitespace." Hello".lstrip()"Hello"
rstrip([chars])Removes trailing characters or whitespace."Hello ".rstrip()"Hello"
partition(separator)Splits the string at the first occurrence of the separator."Hello, world!".partition(" ")('Hello,', ' ', 'world!')
rpartition(separator)Splits the string at the last occurrence of the separator."Hello, world!".rpartition(" ")('Hello,', ' ', 'world!')
isidentifier()Checks if the string is a valid identifier."variable_name".isidentifier()True
istitle()Checks if the string is titled correctly."Hello World".istitle()True