Python Strings
A string (str) Immutable is a sequence of characters. Strings are how Python represents text, and they support indexing, slicing, looping, and a large set of built-in methods.
At a Glance
Section titled “At a Glance”| Task | Syntax | Example |
|---|---|---|
| Create | 'text', "text", '''text''' | name = 'Sam' |
| Length | len(s) | len('hello') gives 5 |
| Index | s[i] | 'hello'[1] gives 'e' |
| Slice | s[start:stop:step] | 'hello'[1:4] gives 'ell' |
| Join | +, join() | 'a' + 'b' gives 'ab' |
| Repeat | * | 'ab' * 3 gives 'ababab' |
| Format | f'{value}' | f'Age: {26}' gives 'Age: 26' |
| Search | in, find() | 'ell' in 'hello' gives True |
| Transform | .upper(), .strip(), .replace() | ' hi '.strip() gives 'hi' |
Creating Strings
Section titled “Creating Strings”Quotes
Section titled “Quotes”Single and double quotes behave identically. Choose whichever lets you avoid escaping.
a = 'Hello'b = "World"c = "It's a sunny day" # Single quote inside double quotesd = 'She said, "Hello World!"' # Double quotes inside single quotese = 'It\'s' # Backslash escapeempty = '' # The empty stringEscape Sequences
Section titled “Escape Sequences”A backslash gives the next character a special meaning.
| Sequence | Meaning |
|---|---|
\n | New line |
\t | Tab |
\\ | A literal backslash |
\' | A literal single quote |
\" | A literal double quote |
print('Line 1\nLine 2')# Line 1# Line 2
print('Name:\tSam') # Name: SamRaw Strings
Section titled “Raw Strings”Prefix a string with r to turn off escape processing. This is useful for file paths and regular expressions.
print('C:\new\table') # Broken: \n and \t are interpreted as escapesprint(r'C:\new\table') # C:\new\tableMulti-line Strings
Section titled “Multi-line Strings”Triple quotes (''' or """) let a string span several lines, preserving the layout exactly as written.
poem = """Roses are red,Violets are blue."""
print(poem)# Roses are red,# Violets are blue.Length, Indexing, and Immutability
Section titled “Length, Indexing, and Immutability”len(s)returns the number of characters.- Zero-based indexing: positions run from
0tolen(s) - 1, sos[0]is the first character. - Negative indexing counts from the right:
s[-1]is the last character ands[-2]is the second to last.
H e l l o w o r l d 0 1 2 3 4 5 6 7 8 9 10 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1my_str = 'Hello world'
print(len(my_str)) # 11print(my_str[0]) # 'H'print(my_str[-1]) # 'd'print(my_str[20]) # IndexError: string index out of rangeImmutability
Section titled “Immutability”Strings cannot be changed in place. You can point a variable at a new string, but you cannot overwrite individual characters.
greeting = 'hello'greeting = 'Hello' # Fine: the name now refers to a new string
greeting[0] = 'J' # TypeError: 'str' object does not support item assignmentTo “modify” a string, build a new one:
greeting = 'hello'
new_greeting = 'J' + greeting[1:] # 'Jello'print(new_greeting)Slicing
Section titled “Slicing”Extract part of a string with string[start:stop:step].
stopis excluded. The slice runs up to, but not including, that index.- Defaults: omitting
startmeans0, omittingstopmeans the end, and omittingstepmeans1. - A negative
stepwalks backward, so[::-1]reverses the string. - Out-of-range slices never raise errors. Python simply stops at the edges.
| Expression | Result for 'Hello world' |
|---|---|
text[1:4] | 'ell' |
text[:5] | 'Hello' |
text[6:] | 'world' |
text[-5:] | 'world' |
text[:-6] | 'Hello' |
text[::2] | 'Hlowrd' |
text[::-1] | 'dlrow olleH' |
text[:] | 'Hello world' (a full copy) |
text[20:] | '' (empty, no error) |
Combining Strings
Section titled “Combining Strings”| Operation | Example | Result |
|---|---|---|
Concatenation (+) | 'A' + ' ' + 'B' | 'A B' |
Augmented assignment (+=) | s += '!' | Appends and reassigns |
Repetition (*) | '-' * 10 | '----------' |
Conversion (str()) | str(26) | '26' |
name = 'John Doe'age = 26
print(name + ' ' + str(age)) # 'John Doe 26'print(name + ' ' + age) # TypeError: can only concatenate str (not "int") to str
message = 'Hello'message += '!' # 'Hello!'
print('=' * 20) # '===================='Formatting with f-Strings
Section titled “Formatting with f-Strings”Prefix a string with f and place expressions inside {}. f-strings convert non-string values automatically and can evaluate any expression.
name = 'John'age = 26
print(f'{name} is {age} years old') # John is 26 years oldprint(f'Summing: {5} + {10} = {5 + 10}') # Summing: 5 + 10 = 15print(f'Shout: {name.upper()}') # Shout: JOHNprint(f'{age = }') # age = 26 (debugging aid, Python 3.8+)Format Specifiers
Section titled “Format Specifiers”Add : after the expression to control how the value is displayed.
| Specifier | Example | Result |
|---|---|---|
.2f | f'{3.14159:.2f}' | '3.14' |
, | f'{1234567:,}' | '1,234,567' |
.1% | f'{0.256:.1%}' | '25.6%' |
05d | f'{42:05d}' | '00042' |
>8 | f"{'hi':>8}" | ' hi' (right-aligned) |
<8 | f"{'hi':<8}" | 'hi ' (left-aligned) |
^8 | f"{'hi':^8}" | ' hi ' (centered) |
!r | f'{name!r}' | "'John'" (shows the repr) |
Other Formatting Styles
Section titled “Other Formatting Styles”print(f'{name} is {age}')The clearest and fastest option. Use this by default.
print('{} is {}'.format(name, age))print('{n} is {a}'.format(n=name, a=age))Useful when the template string is stored separately from the values.
print('%s is %d' % (name, age))Found in older code. Avoid it in new code.
Membership and Comparison
Section titled “Membership and Comparison”in and not in test whether one string appears inside another and return a Boolean.
sentence = 'The quick brown fox'
print('quick' in sentence) # Trueprint('slow' not in sentence) # Trueprint('Quick' in sentence) # False, matching is case-sensitive
print('apple' == 'Apple') # Falseprint('apple' < 'banana') # True, compared alphabetically by character codeprint('Zebra' < 'apple') # True, all uppercase letters sort before lowercaseString Methods
Section titled “String Methods”Call a method with dot notation: variable.method(). Remember that every method returns a new value.
Changing Case
Section titled “Changing Case”| Method | Result | Example |
|---|---|---|
upper() | All uppercase | 'hi'.upper() gives 'HI' |
lower() | All lowercase | 'HI'.lower() gives 'hi' |
capitalize() | First character upper, the rest lower | 'hELLO'.capitalize() gives 'Hello' |
title() | First letter of every word upper | 'hello world'.title() gives 'Hello World' |
swapcase() | Inverts the case of every letter | 'Hi'.swapcase() gives 'hI' |
Cleaning and Replacing
Section titled “Cleaning and Replacing”| Method | Result | Example |
|---|---|---|
strip() | Removes leading and trailing whitespace | ' hi '.strip() gives 'hi' |
lstrip() / rstrip() | Strips only the left or right side | ' hi '.rstrip() gives ' hi' |
strip(chars) | Removes any of the listed characters from both ends | '!!hi!!'.strip('!') gives 'hi' |
replace(old, new) | Replaces every occurrence | 'a-b-c'.replace('-', '/') gives 'a/b/c' |
replace(old, new, n) | Replaces only the first n occurrences | 'a-b-c'.replace('-', '/', 1) gives 'a/b-c' |
removeprefix(p) 3.9+ | Removes a prefix if present | 'unhappy'.removeprefix('un') gives 'happy' |
removesuffix(s) 3.9+ | Removes a suffix if present | 'report.txt'.removesuffix('.txt') gives 'report' |
Searching and Counting
Section titled “Searching and Counting”| Method | Result | Example |
|---|---|---|
find(sub) | Index of the first match, or -1 if absent | 'hello'.find('l') gives 2 |
index(sub) | Like find(), but raises ValueError if absent | 'hello'.index('z') raises an error |
rfind(sub) | Index of the last match, or -1 | 'hello'.rfind('l') gives 3 |
count(sub) | Non-overlapping occurrences | 'banana'.count('an') gives 2 |
startswith(p) | Whether the string begins with p | 'hello'.startswith('he') gives True |
endswith(s) | Whether the string ends with s | 'hello'.endswith('lo') gives True |
Splitting and Joining
Section titled “Splitting and Joining”| Method | Result | Example |
|---|---|---|
split() | Splits on any whitespace, ignoring extra spaces | 'a b c'.split() gives ['a', 'b', 'c'] |
split(sep) | Splits at each separator | 'a,b,,c'.split(',') gives ['a', 'b', '', 'c'] |
split(sep, n) | Splits at most n times | 'a,b,c'.split(',', 1) gives ['a', 'b,c'] |
splitlines() | Splits at line breaks | 'a\nb'.splitlines() gives ['a', 'b'] |
partition(sep) | Splits into (before, sep, after) at the first match | 'key=value'.partition('=') gives ('key', '=', 'value') |
join(items) | Glues strings together using the host string as separator | '-'.join(['a', 'b']) gives 'a-b' |
words = 'one two three'.split() # ['one', 'two', 'three']print('-'.join(words)) # 'one-two-three'
print('-'.join([1, 2, 3])) # TypeError: items must be stringsprint('-'.join(str(n) for n in [1, 2, 3])) # '1-2-3'Testing Content
Section titled “Testing Content”Each of these returns True or False. All return False for an empty string.
| Method | True when the string… | Example |
|---|---|---|
isdigit() | contains only digits | '42'.isdigit() is True, '-5'.isdigit() is False |
isalpha() | contains only letters | 'abc'.isalpha() is True |
isalnum() | contains only letters and digits | 'abc123'.isalnum() is True |
isspace() | contains only whitespace | ' '.isspace() is True |
isupper() | has at least one letter and all letters are uppercase | 'HELLO'.isupper() is True |
islower() | has at least one letter and all letters are lowercase | 'hello'.islower() is True |
Padding and Alignment
Section titled “Padding and Alignment”| Method | Example | Result |
|---|---|---|
zfill(width) | '7'.zfill(3) | '007' |
center(width, fill) | 'hi'.center(8, '*') | '***hi***' |
ljust(width, fill) | 'hi'.ljust(5, '.') | 'hi...' |
rjust(width, fill) | 'hi'.rjust(5, '.') | '...hi' |
Chaining Methods
Section titled “Chaining Methods”Because each method returns a string, you can chain them left to right.
raw_text = ' Hello World '
print(raw_text.strip().lower().replace(' ', '-')) # 'hello-world'Looping Over Strings
Section titled “Looping Over Strings”A string is a sequence, so you can iterate over its characters directly.
for char in 'abc': print(char) # a, b, c
for index, char in enumerate('abc'): print(index, char) # 0 a, 1 b, 2 cPutting It Together
Section titled “Putting It Together”-
Normalize the input. Use
strip(),split(), andlower()ortitle()to remove noise and unify the case. -
Validate it. Use
in,startswith(),isdigit(), orisalpha()to confirm the content is what you expect. -
Transform it. Use
replace(), slicing, andjoin()to reshape the text. -
Present it. Use an f-string to format the final output.
raw_name = ' jOHN dOE '
clean_name = ' '.join(raw_name.split()).title()print(f'Hello, {clean_name}!') # Hello, John Doe!def is_palindrome(text): cleaned = ''.join(ch.lower() for ch in text if ch.isalnum()) return cleaned == cleaned[::-1]
print(is_palindrome('A man, a plan, a canal: Panama')) # Trueprint(is_palindrome('Python')) # FalseCommon Mistakes
Section titled “Common Mistakes”| Mistake | Problem | Fix |
|---|---|---|
s[0] = 'H' | TypeError, strings are immutable | s = 'H' + s[1:] |
s.upper() with no assignment | The new string is discarded | s = s.upper() |
'Age: ' + 26 | TypeError, cannot add str and int | f'Age: {26}' or 'Age: ' + str(26) |
s[len(s)] | IndexError, the last index is len(s) - 1 | s[-1] |
'-'.join([1, 2]) | TypeError, join needs strings | '-'.join(map(str, [1, 2])) |
s.strip('abc') expecting a substring | strip removes any of those characters, not the exact text | Use removeprefix() or removesuffix() |
'hello' in 'Hello World' | Matching is case-sensitive | Compare .lower() versions |
"they're".title() | Gives "They'Re" | Use string.capwords() for simple cases |
'42'.isdigit() to validate numbers | Rejects negatives and decimals | Try int() or float() in a try / except |
Best Practices Checklist
Section titled “Best Practices Checklist”- Pick the quote style that avoids escaping, and stay consistent within a project.
- Use f-strings for formatting instead of
+or%. - Build text from many pieces with
join(), not repeated concatenation. - Remember that strings are immutable, and always capture the result of a method.
- Prefer slicing over manual index arithmetic, and use negative indices to count from the end.
- Normalize with
strip()andlower()before comparing user input. - Use
find()when absence is acceptable andindex()when it should be an error. - Use raw strings (
r'...') for Windows paths and regular expressions.