Skip to content

Python Strings

Strings are one of the most fundamental and commonly used data types in Python. They represent sequences of characters.

Create strings by enclosing characters in single quotes ('...'), double quotes ("..."), or triple quotes ('''...''' or """..."""). Single and double quotes are equivalent for single-line strings. Triple quotes allow strings to span multiple lines.

single_quoted = 'Hello World!'
double_quoted = "Python Programming"
multi_line = '''This is a string
spanning multiple
lines.'''
print(single_quoted)
print(double_quoted)
print(multi_line)

In Python 3, strings handle Unicode characters natively.

Accessing Characters and Substrings (Slicing)

Section titled “Accessing Characters and Substrings (Slicing)”

Strings are sequences, so you can access individual characters using their index (starting from 0) inside square brackets []. You can also extract substrings using slicing [start:stop:step].

#!/usr/bin/env python3
my_string = "Python Programming"
# Access individual characters
print(f"my_string[0]: {my_string[0]}") # Output: P
print(f"my_string[7]: {my_string[7]}") # Output: P
print(f"my_string[-1]: {my_string[-1]}") # Output: g (last character)
print(f"my_string[-3]: {my_string[-3]}") # Output: i (third from end)
# Slicing [start:stop] (stop index is exclusive)
print(f"my_string[0:6]: {my_string[0:6]}") # Output: Python
print(f"my_string[7:18]: {my_string[7:18]}") # Output: Programming
# Slicing shortcuts
print(f"my_string[:6]: {my_string[:6]}") # Output: Python (from beginning to index 5)
print(f"my_string[7:]: {my_string[7:]}") # Output: Programming (from index 7 to end)
print(f"my_string[:]: {my_string[:]}") # Output: Python Programming (a copy of the whole string)
# Slicing with step [start:stop:step]
print(f"my_string[::2]: {my_string[::2]}") # Output: Pto rgamn (every second character)
print(f"my_string[::-1]: {my_string[::-1]}")# Output: gnimmargorP nohtyP (reverse the string)

Strings in Python are immutable, meaning you cannot change a string object in place after it’s created. Operations that seem to modify a string actually create and return a new string object.

#!/usr/bin/env python3
message = "Hello World!"
print(f"Original message: {message}, ID: {id(message)}")
# This creates a NEW string
new_message = message[:6] + "Python!"
print(f"New message: {new_message}, ID: {id(new_message)}")
# Attempting to change a character directly causes an error:
# message[0] = 'J' # Raises TypeError: 'str' object does not support item assignment

Backslash (\) is used to escape characters that have special meaning or are non-printable.

NotationDescription
\nNewline
\tHorizontal Tab
\rCarriage Return
\bBackspace
\fFormfeed
\'Single quote
\"Double quote
\\Backslash itself
\xhhCharacter with hex value hh
\uxxxxUnicode character with 16-bit hex value xxxx
\UxxxxxxxxUnicode character with 32-bit hex value xxxxxxxx
\oooCharacter with octal value ooo (less common)

Example:

print("First line\nSecond line")
print("Path: C:\\Users\\Name")
print('He said, \'Hello!\'')

Prefixing a string literal with r or R creates a raw string, where backslashes are treated as literal characters, not escape sequences. This is particularly useful for regular expressions and Windows file paths.

print(r"This is a raw string.\nNo newline here.")
# Output: This is a raw string.\nNo newline here.
print(R"C:\Users\Name\Documents")
# Output: C:\Users\Name\Documents

Note: A raw string cannot end with a single backslash.

Common operators that work with strings:

OperatorNameDescriptionExample
+ConcatenationJoins two strings'Hello' + ' ' + 'World' -> 'Hello World'
*RepetitionRepeats the string'Hi!' * 3 -> 'Hi!Hi!Hi!'
[]IndexingAccesses a character'Python'[0] -> 'P'
[:]SlicingExtracts a substring'Python'[1:4] -> 'yth'
inMembershipChecks if substring exists'th' in 'Python' -> True
not inMembershipChecks if substring does not exist'x' not in 'Python' -> True

Creating strings with embedded variable values is crucial. Modern Python offers several ways:

Section titled “1. f-Strings (Formatted String Literals) - Recommended (Python 3.6+)”

Prefix the string with f or F. Embed expressions inside curly braces {}.

name = "Alice"
age = 30
pi = 3.14159
# Basic usage
print(f"My name is {name} and I am {age} years old.")
# Expressions inside braces
print(f"Next year, I will be {age + 1}.")
# Formatting specifiers (after colon :)
print(f"Pi is approximately {pi:.2f}") # Format float to 2 decimal places
print(f"Age: {age:03d}") # Pad integer with leading zeros to width 3
print(f"Name aligned: '{name:<10}'") # Left-align in a field of 10 chars
print(f"Name aligned: '{name:>10}'") # Right-align
print(f"Name aligned: '{name:^10}'") # Center-align

Uses curly braces {} as placeholders within the string and calls the format() method.

name = "Bob"
age = 25
# Positional arguments
print("Name: {}, Age: {}".format(name, age))
# Keyword arguments
print("Name: {n}, Age: {a}".format(n=name, a=age))
# Indexed arguments
print("Name: {0}, Age: {1}, Repeat Name: {0}".format(name, age))
# Formatting specifiers (similar to f-strings)
print("Value: {:.3f}".format(10/3)) # Output: Value: 3.333

Uses % placeholders (like %s for string, %d for integer, %f for float) similar to C’s printf. Generally not recommended for new code compared to f-strings or str.format() due to less flexibility and potential for errors.

name = "Charlie"
age = 42
print("My name is %s and weight is %d kg!" % (name, age))
# Formatting specifiers
print("Value: %.2f" % (12.3456)) # Output: Value: 12.35

Table of % format codes (for reference):

Format SymbolConversion
%cSingle character
%sString (or any object using str())
%d or %iSigned decimal integer
%uObsolete (same as %d)
%oOctal integer
%xHex integer (lowercase)
%XHex integer (uppercase)
%fFloating point decimal
%eExponential notation (lowercase ‘e’)
%EExponential notation (uppercase ‘E’)
%gShorter of %f and %e
%GShorter of %f and %E
%%Literal ’%’ character

Python strings have a rich set of built-in methods for common manipulations. Remember these methods return new strings; they don’t modify the original.

Common String Methods:

MethodDescription
capitalize()Returns a copy with first character capitalized, rest lowercase.
casefold()Returns a casefolded copy (aggressive lowercasing for caseless matching).
center(width[, fillchar])Returns centered string within width, padding with fillchar (default space).
count(sub[, start[, end]])Returns the number of non-overlapping occurrences of substring sub.
encode(encoding='utf-8', errors='strict')Returns bytes object representing the string encoded in encoding.
endswith(suffix[, start[, end]])Returns True if string ends with suffix.
expandtabs(tabsize=8)Returns copy with tab characters (\t) replaced by spaces.
find(sub[, start[, end]])Returns lowest index where sub is found, or -1 if not found.
index(sub[, start[, end]])Like find(), but raises ValueError if sub not found.
isalnum()Returns True if all chars are alphanumeric and >= 1 char.
isalpha()Returns True if all chars are alphabetic and >= 1 char.
isascii()Returns True if string is empty or all chars are ASCII.
isdecimal()Returns True if all chars are decimal characters and >= 1 char.
isdigit()Returns True if all chars are digits and >= 1 char.
isidentifier()Returns True if string is a valid Python identifier.
islower()Returns True if all cased chars are lowercase and >= 1 cased char.
isnumeric()Returns True if all chars are numeric characters and >= 1 char.
isprintable()Returns True if all chars are printable or string is empty.
isspace()Returns True if all chars are whitespace and >= 1 char.
istitle()Returns True if string is titlecased and >= 1 char.
isupper()Returns True if all cased chars are uppercase and >= 1 cased char.
join(iterable)Concatenates elements of iterable (must be strings) using the string as a separator.
ljust(width[, fillchar])Returns left-justified string within width.
lower()Returns copy with all cased characters converted to lowercase.
lstrip([chars])Returns copy with leading characters removed (default whitespace).
maketrans(x[, y[, z]])Returns a translation table for translate().
partition(sep)Splits string at first occurrence of sep, returns tuple (before, sep, after).
removeprefix(prefix)Returns copy with prefix removed if string starts with it (Python 3.9+).
removesuffix(suffix)Returns copy with suffix removed if string ends with it (Python 3.9+).
replace(old, new[, count])Returns copy with occurrences of old replaced by new (optionally up to count times).
rfind(sub[, start[, end]])Like find() but searches from the right.
rindex(sub[, start[, end]])Like index() but searches from the right.
rjust(width[, fillchar])Returns right-justified string within width.
rpartition(sep)Like partition() but splits at the last occurrence of sep.
rsplit(sep=None, maxsplit=-1)Like split() but splits from the right.
rstrip([chars])Returns copy with trailing characters removed (default whitespace).
split(sep=None, maxsplit=-1)Returns a list of words, using sep as delimiter (default whitespace), splitting at most maxsplit times.
splitlines(keepends=False)Returns a list of lines, breaking at line boundaries.
startswith(prefix[, start[, end]])Returns True if string starts with prefix.
strip([chars])Returns copy with leading/trailing characters removed (default whitespace).
swapcase()Returns copy with uppercase chars converted to lowercase and vice versa.
title()Returns titlecased version (words start uppercase, rest lowercase).
translate(table)Returns copy with characters mapped through table (from maketrans).
upper()Returns copy with all cased characters converted to uppercase.
zfill(width)Returns copy left-padded with ‘0’s to specified width.

Example Usage of Methods:

text = " Hello World! "
print(f"Original: '{text}'")
print(f"strip(): '{text.strip()}'")
print(f"lower(): '{text.lower()}'")
print(f"upper(): '{text.upper()}'")
print(f"replace('o', 'X'): '{text.replace('o', 'X')}'")
print(f"split(): {text.split()}") # Splits by whitespace
words = ["Python", "is", "fun"]
separator = " "
print(f"join(): '{separator.join(words)}'")
print(f"startswith(' H'): {text.startswith(' H')}")
print(f"find('World'): {text.find('World')}")