🎯 Learning Objectives
- Create strings using single, double, and triple quotes
- Access individual characters with indexing and extract substrings with slicing
- Use common string methods:
upper(),lower(),strip(),split(),join(),replace(),find() - Format strings with f-strings (formatted string literals)
- Understand escape characters and raw strings
Creating Strings
A string (str) is a sequence of characters.
In Python you can define strings with single quotes, double quotes, or triple quotes:
# All three produce the same type
single = 'Hello'
double = "Hello"
triple = """Hello"""
# Use the other quote type to include quotes in text
dialogue = "She said 'hi' to me."
html_tag = '<a href="url">link</a>'
# Triple quotes preserve newlines
poem = """Roses are red,
Violets are blue,
Python is great,
And so are you."""
string_creation.py
Indexing
Each character in a string has a position called an index. Python uses zero-based indexing — the first character is at position 0.
word = "Python"
# P y t h o n
# 0 1 2 3 4 5
# -6 -5 -4 -3 -2 -1
print(word[0]) # P
print(word[5]) # n
print(word[-1]) # n (last character)
print(word[-2]) # o (second from end)
indexing.py
IndexError:
"hi"[5] → IndexError: string index out of range.
Slicing
Slicing extracts a substring using the syntax
string[start:stop:step]. The stop index is
exclusive (not included).
s = "Hello, World!"
print(s[0:5]) # Hello
print(s[7:12]) # World
print(s[:5]) # Hello (start defaults to 0)
print(s[7:]) # World! (stop defaults to end)
print(s[::2]) # Hlo ol! (every 2nd character)
print(s[::-1]) # !dlroW ,olleH (reversed)
slicing.py
IndexError. If your indices are out of range,
Python simply returns what it can — even an empty string.
String Length & Membership
msg = "Hello, World!"
print(len(msg)) # 13 (includes space, comma, exclamation)
print("World" in msg) # True
print("world" in msg) # False — case-sensitive!
print("xyz" not in msg) # True
length.py
Common String Methods
Strings have dozens of built-in methods. Here are the ones you'll use daily:
| Method | What it does | Example → Result |
|---|---|---|
.upper() | All uppercase | "hi".upper() → "HI" |
.lower() | All lowercase | "HI".lower() → "hi" |
.title() | Title Case | "hello world".title() → "Hello World" |
.strip() | Remove leading/trailing whitespace | " hi ".strip() → "hi" |
.lstrip() / .rstrip() | Strip left / right only | " hi ".lstrip() → "hi " |
.startswith(x) | True if starts with x | "Python".startswith("Py") → True |
.endswith(x) | True if ends with x | "file.py".endswith(".py") → True |
.replace(a, b) | Replace all occurrences of a with b | "hello".replace("l", "L") → "heLLo" |
.find(x) | Index of first x (−1 if not found) | "hello".find("ll") → 2 |
.count(x) | Count occurrences of x | "banana".count("a") → 3 |
.split(sep) | Split into a list | "a,b,c".split(",") → ["a","b","c"] |
sep.join(list) | Join a list into a string | "-".join(["a","b"]) → "a-b" |
.isdigit() | True if all chars are digits | "123".isdigit() → True |
.isalpha() | True if all chars are letters | "abc".isalpha() → True |
email = " User@Example.COM "
clean = email.strip().lower()
print(clean) # "user@example.com"
domain = clean.split("@")[1]
print(domain) # "example.com"
csv_line = "Alice,30,Engineer"
parts = csv_line.split(",")
print(parts) # ['Alice', '30', 'Engineer']
rejoined = " | ".join(parts)
print(rejoined) # "Alice | 30 | Engineer"
methods_demo.py
.upper() don't modify the
original — they return a new string. Always assign the result:
name = name.strip().
Concatenation & Repetition
# Concatenation with +
first = "Hello"
last = "World"
full = first + ", " + last + "!"
print(full) # Hello, World!
# Repetition with *
line = "-" * 40
print(line) # ----------------------------------------
# You can only concatenate str + str
# print("age: " + 30) ← TypeError!
print("age: " + str(30)) # OK
concat.py
f-Strings (Formatted String Literals)
Introduced in Python 3.6, f-strings are the modern way to embed
expressions inside strings. Prefix the string with f and put expressions
in curly braces:
name = "Alice"
age = 30
# Basic interpolation
print(f"My name is {name} and I am {age} years old.")
# Expressions inside braces
print(f"Next year I'll be {age + 1}.")
print(f"Name uppercase: {name.upper()}")
# Format specifiers
pi = 3.14159265
print(f"Pi to 2 decimals: {pi:.2f}") # 3.14
print(f"Large number: {1000000:,}") # 1,000,000
print(f"Padded: {42:>10}") # 42
print(f"Percentage: {0.856:.1%}") # 85.6%
fstrings.py
.format() and far more readable than
%-formatting. Use them whenever you're on Python 3.6+.
Older formatting (for reference)
# .format() method (Python 3.0+)
print("Hello, {}! You are {}.".format(name, age))
# %-formatting (legacy — avoid in new code)
print("Hello, %s! You are %d." % (name, age))
old_format.py
Escape Characters
Escape sequences start with a backslash \ and represent special characters:
| Sequence | Meaning |
|---|---|
\n | Newline |
\t | Tab |
\\ | Literal backslash |
\' | Single quote (inside single-quoted string) |
\" | Double quote (inside double-quoted string) |
print("Line 1\nLine 2")
# Line 1
# Line 2
print("Column1\tColumn2")
# Column1 Column2
print("She said \"hello\"")
# She said "hello"
# Raw strings — backslashes are literal (useful for regex, paths)
path = r"C:\Users\name\documents"
print(path) # C:\Users\name\documents
escapes.py
Iterating Over Strings
Strings are sequences, so you can loop through each character:
word = "Python"
for char in word:
print(char, end=" ")
# P y t h o n
# With index using enumerate()
for i, char in enumerate(word):
print(f"{i}: {char}")
# 0: P
# 1: y
# 2: t ... etc.
iteration.py
Primary sources: Python Docs — str type · Python Docs — f-strings
Ask your AI tutor! Want to know the difference between
.find() and .index()? Unsure when to use .split()
vs a regex? Ask — string manipulation is 60% of real-world Python.
💻 Exercises
Write a function (or script) that takes an email string like
" User@Example.COM ", strips whitespace, converts to lowercase,
and prints the cleaned email plus its domain (everything after @).
Show solution
raw = " User@Example.COM "
email = raw.strip().lower()
domain = email.split("@")[1]
print(f"Email: {email}") # user@example.com
print(f"Domain: {domain}") # example.com
Given a full name like "guido van rossum", produce the initials
in uppercase: "GVR". Hint: .split() and a loop or
comprehension.
Show solution
name = "guido van rossum"
parts = name.split()
initials = ""
for part in parts:
initials += part[0].upper()
print(initials) # GVR
# One-liner alternative:
initials = "".join(p[0].upper() for p in name.split())
print(initials) # GVR
Write code that checks if a word is a palindrome (reads the same forwards and
backwards). Test with "racecar" and "hello".
Ignore case.
Show solution
word = "Racecar"
clean = word.lower()
is_palindrome = clean == clean[::-1]
print(f"'{word}' is a palindrome: {is_palindrome}")
# 'Racecar' is a palindrome: True
word2 = "hello"
clean2 = word2.lower()
print(f"'{word2}' is a palindrome: {clean2 == clean2[::-1]}")
# 'hello' is a palindrome: False