Python Strings
Learn how to work with strings in Python, including creation, manipulation, and formatting.
Strings
Strings in Python are surrounded by either single quotation marks, or double quotation marks.
'hello' is the same as "hello".
You can display a string literal with the print() function:
Example
print("Hello")
print('Hello')Assign String to a Variable
Assigning a string to a variable is done with the variable name followed by an equal sign and the string:
Example
a = "Hello"
print(a)Multiline Strings
You can assign a multiline string to a variable by using three quotes:
Example
a = """Lorem ipsum dolor sit amet,
consectetur adipiscing elit,
sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua."""
print(a)Or three single quotes:
Example
a = '''Lorem ipsum dolor sit amet,
consectetur adipiscing elit,
sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua.'''
print(a)Strings are Arrays
Like many other popular programming languages, strings in Python are arrays of bytes representing unicode characters.
However, Python does not have a character data type, a single character is simply a string with a length of 1.
Square brackets can be used to access elements of the string.
Example
a = "Hello, World!"
print(a[1])Looping Through a String
Since strings are arrays, we can loop through the characters in a string, with a for loop.
Example
for x in "banana":
print(x)String Length
To get the length of a string, use the len() function.
Example
a = "Hello, World!"
print(len(a))Check String
To check if a certain phrase or character is present in a string, we can use the keyword in.
Example
txt = "The best things in life are free!"
print("free" in txt)Use it in an if statement:
Example
txt = "The best things in life are free!"
if "free" in txt:
print("Yes, 'free' is present.")Check if NOT
To check if a certain phrase or character is NOT present in a string, we can use the keyword not in.
Example
txt = "The best things in life are free!"
print("expensive" not in txt)Use it in an if statement:
Example
txt = "The best things in life are free!"
if "expensive" not in txt:
print("No, 'expensive' is NOT present.")Slicing Strings
Slice with s[start:stop:step]. start is included, stop is excluded, and negative indexes count from the end.
s = "Python"
print(s[0]) # P
print(s[-1]) # n (last character)
print(s[0:3]) # Pyt
print(s[2:]) # thon
print(s[::-1]) # nohtyP (reverse)
print(len(s)) # 6Essential String Methods
| Method | Example | Result |
|---|---|---|
.upper() / .lower() | "Hi".upper() | "HI" |
.strip() | " hi ".strip() | "hi" |
.replace() | "a-b".replace("-", " ") | "a b" |
.split() | "a,b".split(",") | ["a", "b"] |
.join() | "-".join(["a", "b"]) | "a-b" |
.find() | "abc".find("b") | 1 |
Strings are immutable, so every method returns a new string — the original is unchanged.
f-strings: The Modern Way to Format
name, score = "Sam", 92.5
print(f"{name} scored {score}") # Sam scored 92.5
print(f"{score:.0f}%") # 92% (format spec)
print(f"{name.upper()} = {score * 2}") # expressions work insideTry It Yourself
Exercise 1: Given s = " Hello World ", trim the spaces and print it in lowercase.
Show solution
s = " Hello World "
print(s.strip().lower()) # hello worldExercise 2: Count how many times "a" appears in "banana".
Show solution
print("banana".count("a")) # 3Exercise 3: Reverse the string "stressed".
Show solution
print("stressed"[::-1]) # dessertsKey Takeaways
- Strings are immutable, ordered sequences of characters.
- Slice with
[start:stop:step];[::-1]reverses. - Methods like
.strip(),.split(),.join()return new strings. - Prefer f-strings for formatting.
📘 Real-World Deep Dive
Strings are how every program talks to humans — logs, APIs, file paths. Knowing <code>str</code> vs. <code>bytes</code>, slicing, formatting, and the rich method set avoids an entire class of bugs.
Real-Life Scenario
A small CLI that normalises input text — trim, lower-case, replace diacritics, and emit a slug safe for filenames.
Real-Life Example
import re
import unicodedata
def slugify(text: str, *, max_len: int = 60) -> str:
folded = unicodedata.normalize("NFKD", text)
ascii_only = folded.encode("ascii", "ignore").decode("ascii")
lowered = ascii_only.lower()
slug = re.sub(r"[^a-z0-9]+", "-", lowered).strip("-")
return slug[:max_len].rstrip("-") or "untitled"
for s in [
"Hello, World!",
"Café déjà vu — été 2026",
" Multiple ___spaces___ here ",
"🚀 emoji 🚀 only 🚀",
"",
]:
print(f"{s!r:>40} -> {slugify(s)!r}")Expected Output
'Hello, World!' -> 'hello-world'
'Café déjà vu — été 2026' -> 'cafe-deja-vu-ete-2026'
' Multiple ___spaces___ here ' -> 'multiple-spaces-here'
'🚀 emoji 🚀 only 🚀' -> 'emoji-only'
'' -> 'untitled'Common mistakes
str.encode("ascii")raisesUnicodeEncodeError; use"ignore"or"replace"deliberately.- Comparing
strtobytesraisesTypeError; normalise at the I/O boundary. str.strip()by default strips ASCII whitespace — Unicode whitespace (e.g. thin space\u2009) survives.
🚀 Performance & Best Practices
- Use
f"... {name!r}"rather thanstr.formatfor hot paths — f-strings are compiled into the best bytecode. - For very large strings, build with
"".join(parts)instead of+=—stris immutable. str.translateis the fastest way to apply bulk char-level substitutions.
🧪 Try It Yourself
- Extend
slugifyto collapse runs of digits into shorter markers. - Write tests with
pytest.mark.parametrizecovering diacritics, emoji, and empty input. - Compare
slugifyruntime vs.python-slugifyfor a 1 MB input.