String Fundamentals
Strings are one of the most frequently used data types in any program. Every time you display a message, read a file, process user input, or build a URL, you're working with strings. In Python, strings are immutable sequences of Unicode characters — meaning once created, they can't be modified. Every string method returns a new string.
Creating Strings
Python offers several ways to create strings. Single quotes and double quotes are identical. Triple quotes let you span multiple lines. Raw strings ignore escape characters:
# Single and double quotes are identical
s1 = 'hello'
s2 = "hello"
print(s1 == s2) # True
# Use the other style to include quotes
message = "It's a beautiful day"
html = '<div class="box">content</div>'
# Triple quotes for multiline
poem = """Roses are red,
Violets are blue,
Python is awesome,
And so are you."""
print(poem)
# Raw strings — no escape processing (great for regex and paths)
path = r"C:\Users\name\documents"
print(path) # Backslashes are literal, not escape chars
True Roses are red, Violets are blue, Python is awesome, And so are you. C:\Users\name\documents
String Indexing and Slicing
Strings are sequences, so you can access individual characters by index and extract substrings with slicing. Remember: indexing starts at 0, and negative indices count from the end:
s = "Python"
# Indexing
print(s[0]) # P (first)
print(s[-1]) # n (last)
print(s[2]) # t (third)
# Slicing: s[start:stop:step]
print(s[1:4]) # yth (index 1,2,3)
print(s[:3]) # Pyt (first 3)
print(s[3:]) # hon (from index 3 on)
print(s[::-1]) # nohtyP (reversed!)
print(s[::2]) # Pto (every other char)
P n t yth Pyt hon nohtyP Pto
s[start:stop:step]. The stop index is excluded. Negative indices count from the end. s[::-1] reverses a string.f-strings: Modern String Formatting
f-strings (formatted string literals, Python 3.6+) are the clearest and fastest way to embed expressions in strings. Prefix the string with f and put expressions inside curly braces:
name = "Alice"
age = 30
balance = 1234.5678
# Basic embedding
print(f"{name} is {age} years old")
# Expressions inside braces
print(f"Next year: {age + 1}")
print(f"Name uppercased: {name.upper()}")
# Format specifiers
print(f"Balance: ${balance:,.2f}") # Comma + 2 decimals
print(f"Percentage: {0.856:.1%}") # As percentage
print(f"{name:>15}") # Right-align in 15 chars
print(f"{name:*^15}") # Center with * padding
print(f"{'yes' if age > 18 else 'no'}") # Inline conditional
# Debugging (Python 3.8+)
x = 42
print(f"{x = }") # Prints: x = 42
Alice is 30 years old
Next year: 31
Name uppercased: ALICE
Balance: $1,234.57
Percentage: 85.6%
Alice
*****Alice*****
yes
x = 42Essential String Methods
Python strings come with dozens of built-in methods. Here are the ones you'll use most often. Remember: all string methods return new strings because strings are immutable.
s = " Hello, World! "
# Cleaning
print(s.strip()) # "Hello, World!" (remove whitespace)
print(s.lstrip()) # "Hello, World! " (left only)
print(s.rstrip()) # " Hello, World!" (right only)
# Case
print(s.strip().lower()) # "hello, world!"
print(s.strip().upper()) # "HELLO, WORLD!"
print("hello world".title()) # "Hello World"
# Searching
print("World" in s) # True
print(s.find("World")) # 9 (index, -1 if not found)
print(s.count("l")) # 3
# Replacing
print(s.strip().replace("World", "Python")) # "Hello, Python!"
# Splitting and joining
words = "one,two,three".split(",")
print(words) # ['one', 'two', 'three']
print(" | ".join(words)) # "one | two | three"
# Checking
print("hello123".isalnum()) # True (letters + digits)
print("hello".isalpha()) # True (letters only)
print("12345".isdigit()) # True (digits only)
print("hello".startswith("he")) # True
print("hello".endswith("lo")) # True
Hello, World! True 9 3 Hello, Python! ['one', 'two', 'three'] one | two | three True True True True True
| Method | What It Does | Returns |
|---|---|---|
.strip() | Remove leading/trailing whitespace | New string |
.split(sep) | Split into list by separator | List of strings |
.join(list) | Join list with separator | New string |
.replace(old, new) | Replace occurrences | New string |
.find(sub) | Find substring index | int (-1 if missing) |
.startswith(prefix) | Check prefix | bool |
.upper() / .lower() | Change case | New string |
⚠️ Common Mistake: String Concatenation in Loops
Wrong:
result = ""
for word in words:
result += word + " " # Creates a NEW string every iteration!
Why: Strings are immutable. Each += creates a new string object and copies all previous characters. For n words, this is O(n²) — quadratically slow.
Instead:
result = " ".join(words) # O(n) — builds the string once
🔍 Deep Dive: String Interning
Python caches (interns) small strings and commonly used strings for performance. This means is sometimes works for string comparison: "hello" is "hello" may be True. But never rely on this. Always use == for value comparison. is checks identity (same object in memory), == checks equality (same value).