Strings
Strings are a fundamental data type used to represent text. 📝 Whether it's a single
character or a paragraph, any text enclosed within either single quotes (' ') or double quotes
(" ") is considered a string in Python. Strings serve as the building blocks for text
manipulation, and Python equips us with a rich set of built-in methods, or manipulators, to
operate on strings. You can perform operations like changing letter cases, slicing (and more)
to manipulate and extract valuable information from text data.
Creating a string is straightforward. You assign any alphanumeric value inside single or double
quotes to a variable name using the assignment operator (=):
| Declaring Basic Strings |
|---|
| name = "Brad"
location = 'Halifax'
occupation = 'Kubernetes Guy'
empty_string = "" # A string with nothing in it
|
Single vs Double Quotes
Strings can be enclosed in either single quotes ('') or double quotes (""), allowing you
flexibility in your code. The main benefit? Use one to contain the other:
message = "It's a beautiful day!" # Single quote inside double quotes
quote = 'He said "Hello" to me' # Double quotes inside single quotes
escaped = "He said \"Hello\" to me" # Or use backslash to escape
Concatenating Strings
Strings can be combined with simple plus (+) signs:
| Basic Concatenation |
|---|
| first_name = "Albert"
last_name = "Einstien"
print("There was a famous scientist named " + first_name + " " + last_name + ".")
|
Would output:
There was a famous scientist named Albert Einstien.
F-Strings
Introduced in version 3.6 (3.13.3 is current as of Summer 2025), "F-Strings" are a much-improved
way to build strings in Python. Once you try them, you'll never go back. ✨ Simply precede a string with f before the opening quotation. Then,
any variable can be surrounded by curly braces {}, removing the need to cast variables of various
types. For example:
| F-Strings |
|---|
| name = "Jim"
age = 32
print(f"My name is {name} and I am {age} years old!")
|
Would produce:
My name is Jim and I am 32 years old!
String Methods
Strings can accept methods which alter the contents of the string. Some examples of string methods
that are built into Python include:
| Sample String Methods |
|---|
| book_title = "mastery by Robert greene"
print(book_title.upper())
print(book_title.lower())
print(book_title.title())
print(book_title.capitalize())
|
Returns:
MASTERY BY ROBERT GREENE
mastery by robert greene
Mastery by Robert Greene
Mastery by robert greene
Adding & Removing Whitespace
Special characters can be added to strings that add whitespace. These include:
\t which adds a tab (4 spaces)
\n which adds a newline
| Adding Tabs and New Lines to Output |
|---|
| print("Hello, I'm \t \t Brad!")
print("and you are learning \n \t Python")
|
Returns:
Hello, I'm Brad!
and you are learning
Python
Whitespace can also be stripped out using string methods. These include strip() (both sides),
rstrip() (right side), and lstrip() (left side).
| Stripping Whitespace in Strings |
|---|
| name = " Albert Einstein "
print("Hello I am " + name + ".") # whitespace remains
print("Hello I am " + name.strip() + ".") # whitespace stripped
print("Hello I am " + name.rstrip() + ".") # whitespace on righ stripped
print("Hello I am " + name.lstrip() + ".") # whitespace on left stripped
|
Would result with:
Hello I am Albert Einstein .
Hello I am Albert Einstein.
Hello I am Albert Einstein.
Hello I am Albert Einstein .
Slicing
Strings can also be sliced - see Slicing Sequences
for more details.
String Length and Indexing
Getting the Length
The len() function tells you how many characters are in a string:
| String Length |
|---|
| message = "Hello, World!"
print(len(message)) # 13
empty = ""
print(len(empty)) # 0
# Useful for validation
username = "bob"
if len(username) < 3:
print("Username too short!")
|
Accessing Individual Characters
Strings are sequences of characters, and you can access each character by its position
(index). Python uses zero-based indexing — the first character is at index 0:
| String Indexing |
|---|
| word = "Python"
# 012345 ← indices
print(word[0]) # 'P' — first character
print(word[1]) # 'y' — second character
print(word[5]) # 'n' — sixth character (last one)
|
Negative Indexing
Python also supports negative indices, which count from the end. This is incredibly useful
when you want the last character without knowing the string's length:
| Negative Indexing |
|---|
| word = "Python"
# -6-5-4-3-2-1 ← negative indices
print(word[-1]) # 'n' — last character
print(word[-2]) # 'o' — second to last
print(word[-6]) # 'P' — first character (same as word[0])
|
Index Out of Range
Accessing an index that doesn't exist raises an IndexError:
word = "Python"
print(word[10]) # IndexError: string index out of range
print(word[-10]) # IndexError: string index out of range
Always check len() if you're unsure, or use exception handling.
Searching Within Strings
The in Operator
The simplest way to check if a substring exists:
| Checking for Substrings |
|---|
| sentence = "The quick brown fox jumps over the lazy dog"
print("fox" in sentence) # True
print("cat" in sentence) # False
print("Fox" in sentence) # False — case-sensitive!
# Great for conditionals
if "error" in log_message.lower():
print("Something went wrong!")
|
find() and index()
To get the position of a substring:
| Finding Substring Positions |
|---|
| text = "Hello, World!"
# find() returns -1 if not found
print(text.find("World")) # 7
print(text.find("Python")) # -1
# index() raises ValueError if not found
print(text.index("World")) # 7
# print(text.index("Python")) # ValueError!
# Find starting from a specific position
text = "banana"
print(text.find("a")) # 1 — first 'a'
print(text.find("a", 2)) # 3 — first 'a' after index 2
|
find() vs index()
Use find() when the substring might not exist (returns -1).
Use index() when it should exist and absence is an error.
count()
Count how many times a substring appears:
| Counting Substrings |
|---|
| text = "banana"
print(text.count("a")) # 3
print(text.count("na")) # 2
print(text.count("x")) # 0
# Practical example
sentence = "the cat sat on the mat"
print(sentence.count("the")) # 2
|
Replacing and Modifying
replace()
Substitute parts of a string:
| Replacing Substrings |
|---|
| message = "Hello, World!"
new_message = message.replace("World", "Python")
print(new_message) # "Hello, Python!"
# Replace all occurrences
text = "one fish, two fish, red fish, blue fish"
print(text.replace("fish", "cat"))
# "one cat, two cat, red cat, blue cat"
# Limit replacements
print(text.replace("fish", "cat", 2))
# "one cat, two cat, red fish, blue fish"
|
Strings Are Immutable
Strings cannot be modified in place. Methods like replace() return a new string;
the original is unchanged:
original = "Hello"
original.upper() # Returns "HELLO" but doesn't change original
print(original) # Still "Hello"
# To "change" a string, reassign it
original = original.upper()
print(original) # Now "HELLO"
Other Useful Modifications
| More String Modifications |
|---|
| text = " hello world "
# Centering and padding
print(text.strip().center(20, "-")) # "---hello world----"
print("42".zfill(5)) # "00042" — pad with zeros
# Checking content
print("hello123".isalnum()) # True — letters and numbers only
print("hello".isalpha()) # True — letters only
print("12345".isdigit()) # True — digits only
print("HELLO".isupper()) # True
print("hello".islower()) # True
# Starting and ending
filename = "document.pdf"
print(filename.startswith("doc")) # True
print(filename.endswith(".pdf")) # True
print(filename.endswith((".pdf", ".doc", ".txt"))) # True — multiple options!
|
Splitting and Joining
These two methods are workhorses for text processing. 🐴
split()
Break a string into a list of parts:
| Splitting Strings |
|---|
| # Split on whitespace (default)
sentence = "The quick brown fox"
words = sentence.split()
print(words) # ['The', 'quick', 'brown', 'fox']
# Split on a specific delimiter
data = "apple,banana,cherry"
fruits = data.split(",")
print(fruits) # ['apple', 'banana', 'cherry']
# Split with a limit
text = "one two three four five"
print(text.split(" ", 2)) # ['one', 'two', 'three four five']
# Split on newlines
multiline = "line1\nline2\nline3"
lines = multiline.split("\n")
print(lines) # ['line1', 'line2', 'line3']
# Or use splitlines() for cross-platform newline handling
print(multiline.splitlines()) # ['line1', 'line2', 'line3']
|
join()
The opposite of split — combine a list into a single string:
| Joining Strings |
|---|
| words = ['The', 'quick', 'brown', 'fox']
# Join with spaces
sentence = " ".join(words)
print(sentence) # "The quick brown fox"
# Join with any separator
print("-".join(words)) # "The-quick-brown-fox"
print("".join(words)) # "Thequickbrownfox"
print(", ".join(words)) # "The, quick, brown, fox"
# Build a path
path_parts = ["home", "user", "documents"]
print("/".join(path_parts)) # "home/user/documents"
|
join() is Faster Than + Concatenation
When combining many strings, join() is significantly more efficient than using +
in a loop:
# Slow (creates many intermediate strings)
result = ""
for word in words:
result = result + word + " "
# Fast (single operation)
result = " ".join(words)
Multi-line Strings
For text that spans multiple lines, use triple quotes:
| Multi-line Strings |
|---|
| # Triple double quotes
poem = """Roses are red,
Violets are blue,
Python is awesome,
And so are you!"""
print(poem)
# Triple single quotes work too
sql_query = '''
SELECT *
FROM users
WHERE active = true
ORDER BY name
'''
|
Multi-line strings preserve all whitespace and newlines exactly as written. They're perfect
for:
- Long text blocks
- SQL queries
- HTML/JSON templates
- Docstrings (documentation)
Removing Leading Whitespace
If indentation in your code adds unwanted leading spaces, use textwrap.dedent():
import textwrap
def example():
query = textwrap.dedent("""
SELECT *
FROM users
WHERE active = true
""").strip()
print(query)
Raw Strings
Prefix a string with r to create a "raw" string where backslashes are treated literally:
| Raw Strings |
|---|
| # Normal string — backslash is an escape character
print("Hello\nWorld")
# Hello
# World
# Raw string — backslash is just a backslash
print(r"Hello\nWorld")
# Hello\nWorld
# Useful for Windows paths
path = r"C:\Users\Documents\file.txt"
print(path) # C:\Users\Documents\file.txt
# Essential for regular expressions
import re
pattern = r"\d{3}-\d{4}" # Matches "123-4567"
|
Without the r prefix, you'd need to escape every backslash: "C:\\Users\\Documents\\file.txt".
Raw strings save you from backslash madness. 🎭
F-strings can do more than just insert variables — they support formatting expressions:
| Advanced F-String Formatting |
|---|
| # Number formatting
price = 49.99
print(f"Price: ${price:.2f}") # Price: $49.99
print(f"Price: ${price:10.2f}") # Price: $ 49.99 (padded)
pi = 3.14159265359
print(f"Pi: {pi:.4f}") # Pi: 3.1416 (4 decimal places)
# Thousands separator
big_number = 1234567890
print(f"{big_number:,}") # 1,234,567,890
# Percentage
ratio = 0.856
print(f"Score: {ratio:.1%}") # Score: 85.6%
# Padding and alignment
name = "Bob"
print(f"{name:>10}") # " Bob" — right-aligned
print(f"{name:<10}") # "Bob " — left-aligned
print(f"{name:^10}") # " Bob " — centered
print(f"{name:*^10}") # "***Bob****" — centered with fill character
# Expressions inside f-strings
x = 10
print(f"{x} squared is {x**2}") # 10 squared is 100
print(f"{'hello'.upper()}") # HELLO
|
Converting To and From Strings
| Type Conversion |
|---|
| # Numbers to string
age = 25
age_str = str(age)
print("I am " + age_str) # I am 25
# String to numbers
number = int("42")
decimal = float("3.14")
# Check if a string is a valid number
user_input = "123"
if user_input.isdigit():
value = int(user_input)
else:
print("Not a valid number")
# ord() and chr() — character ↔ ASCII/Unicode
print(ord("A")) # 65
print(chr(65)) # 'A'
print(ord("🐍")) # 128013
|
Key Takeaways
| Concept |
What to Remember |
| Indexing |
Zero-based: word[0] is first, word[-1] is last |
| Immutable |
Strings can't be changed; methods return new strings |
in operator |
"sub" in string checks for substring |
| find() vs index() |
find() returns -1, index() raises error |
| split() / join() |
Convert between strings and lists |
| Triple quotes |
Multi-line strings: """text""" |
| Raw strings |
r"path\to\file" — backslashes are literal |
| F-string formatting |
f"{value:.2f}" for formatted output |