Skip to content

Python 3 - Strings

Strings are one of the most fundamental and commonly used data types in Python. They represent sequences of characters. You create strings by enclosing characters within either single quotes (’) or double quotes (”). Python treats both types of quotes identically. Assigning a string to a variable is straightforward:

message = 'Hello World!'
subject = "Python Programming"

You can also use triple quotes (''' or """) to create multi-line strings or strings containing both single and double quotes without needing to escape them.

multi_line_string = '''This is a string
that spans multiple
lines.'''
quoted_string = """He said, 'Python is fun!'"""

Strings are sequences, meaning their characters are ordered. You can access individual characters or parts of the string (substrings) using indexing and slicing with square brackets [].

Indexing starts at 0 for the first character. Negative indices count from the end (-1 is the last character).

Slicing extracts a portion of the string using [start:end]. The start index is inclusive, and the end index is exclusive. Omitting start defaults to the beginning, and omitting end defaults to the end.

#!/usr/bin/env python3
message = 'Hello World!'
subject = "Python Programming"
# Accessing single characters
print(f"message[0]: {message[0]}") # Output: H
print(f"message[-1]: {message[-1]}") # Output: !
# Slicing to get substrings
print(f"subject[0:6]: {subject[0:6]}") # Output: Python
print(f"subject[7:]: {subject[7:]}") # Output: Programming
print(f"subject[:6]: {subject[:6]}") # Output: Python
print(f"message[::2]: {message[::2]}") # Output: HloWrd (every second char)

Executing the code above produces:

message[0]: H
message[-1]: !
subject[0:6]: Python
subject[7:]: Programming
subject[:6]: Python
message[::2]: HloWrd

Strings in Python are immutable, meaning you cannot change an existing string directly (e.g., you can’t assign a new character to a specific index). To ‘update’ a string, you need to create a new string based on the original, possibly combining parts of it with new content.

#!/usr/bin/env python3
message = 'Hello World!'
print(f"Original message: {message}")
# Create a new string by slicing and concatenating
updated_message = message[:6] + 'Python!'
print(f"Updated message: {updated_message}")
# Trying to modify in place (will cause an error)
# message[0] = 'J' # This line would raise a TypeError

Executing the valid code produces:

Original message: Hello World!
Updated message: Hello Python!

Certain characters have special meanings when prefixed with a backslash (\). These are called escape sequences and allow you to include characters like newlines, tabs, or literal backslashes and quotes within your string literals.

Common escape sequences:

SequenceMeaning
\Backslash ()
‘Single quote (’)
“Double quote (”)
\nASCII Linefeed (Newline)
\tASCII Horizontal Tab
\rASCII Carriage Return
\bASCII Backspace
\fASCII Formfeed
\oooCharacter with octal value ooo
\xhhCharacter with hex value hh

Example:

print("This string contains a newline\nand a tab\t character.")
print('You can include \'single quotes\' or \"double quotes\".')
print("To print a literal backslash, use \\.")

Strings support several operators:

OperatorDescriptionExample (a = 'Hello', b = 'Python')
+Concatenation - Joins strings together.a + ' ' + b results in 'Hello Python'
*Repetition - Repeats the string.a * 2 results in 'HelloHello'
[]Indexing - Accesses a single character.a[1] results in 'e'
[:]Slicing - Extracts a substring.a[1:4] results in 'ell'
inMembership - Checks if a substring exists within the string.'H' in a results in True
not inMembership - Checks if a substring does not exist.'M' not in a results in True

If you need to prevent the interpretation of escape sequences, you can create a raw string by prefixing the opening quote with r or R. This is particularly useful for regular expressions or Windows file paths.

# Normal string where \n is a newline
print('C:\some\name')
# Raw string where \n is treated as literal characters
print(r'C:\some\name')

Output:

C:\some
ame
C:\some\name

Note: A raw string cannot end with an odd number of backslashes.

Python offers several ways to format strings, embedding values within them. While the older % operator exists (similar to C’s printf), the modern and preferred methods are f-strings (formatted string literals) and the str.format() method.

Introduced in Python 3.6, f-strings are prefixed with f or F and allow you to embed expressions inside {} directly within the string literal. They are concise and generally the fastest option.

#!/usr/bin/env python3
name = 'Alice'
age = 30
height = 1.68
print(f"My name is {name} and I am {age} years old.")
print(f"{name}'s height is {height:.2f} meters.") # Format height to 2 decimal places
print(f"In 5 years, {name} will be {age + 5}.")

Output:

My name is Alice and I am 30 years old.
Alice's height is 1.68 meters.
In 5 years, Alice will be 35.

The format() method is called on a string literal or variable. Placeholders {} are used within the string, which are then filled by the arguments passed to format().

#!/usr/bin/env python3
name = 'Bob'
age = 25
# Using positional arguments
print("My name is {} and I am {} years old.".format(name, age))
# Using keyword arguments
print("My name is {n} and I am {a} years old.".format(n=name, a=age))
# Using indexed arguments
print("My name is {0} and I am {1} years old. {0} likes Python.".format(name, age))

Output:

My name is Bob and I am 25 years old.
My name is Bob and I am 25 years old.
My name is Bob and I am 25 years old. Bob likes Python.

Both f-strings and str.format() support a powerful mini-language for controlling alignment, padding, number formatting, and more. You can find details in the official Python documentation. [Link to Python format spec mini-language documentation could be added here if external links were allowed].

The % operator can also format strings. It uses format specifiers like %s (string), %d (integer), and %f (float). While you might encounter this in older code, f-strings or str.format() are recommended for new code due to better readability and flexibility.

#!/usr/bin/env python3
name = 'Charlie'
age = 42
print("My name is %s and weight is %d kg!" % (name, age))

Output:

My name is Charlie and weight is 42 kg!

In Python 3, all strings are Unicode strings by default. This means Python handles a wide range of characters from different languages and symbols seamlessly. You don’t need to do anything special (like the u'' prefix used in Python 2) to create Unicode strings.

#!/usr/bin/env python3
unicode_string = "你好世界"
emoji_string = "Python is fun 👍"
print(unicode_string)
print(emoji_string)

While strings are Unicode, you might need to encode strings into a specific byte representation (like UTF-8) for storing in files or sending over networks, or decode bytes back into strings.

#!/usr/bin/env python3
text = "résumé"
encoded_utf8 = text.encode('utf-8') # Encode to bytes
decoded_text = encoded_utf8.decode('utf-8') # Decode back to string
print(f"Original: {text}")
print(f"Encoded (bytes): {encoded_utf8}")
print(f"Decoded: {decoded_text}")

Python strings come with many useful built-in methods for common manipulations. Remember that these methods return new strings, as strings are immutable.

Here are some frequently used methods:

Method SignatureDescription
capitalize()Returns a copy with the first character capitalized and the rest lowercase.
lower()Returns a copy with all characters converted to lowercase.
upper()Returns a copy with all characters converted to uppercase.
title()Returns a title-cased copy (first letter of each word uppercase, rest lowercase).
swapcase()Returns a copy with uppercase characters converted to lowercase and vice versa.
strip([chars])Returns a copy with leading and trailing whitespace (or specified chars) removed.
lstrip([chars])Returns a copy with leading whitespace (or specified chars) removed.
rstrip([chars])Returns a copy with trailing whitespace (or specified chars) removed.
replace(old, new[, count])Returns a copy with occurrences of old substring replaced by new. Optional count limits replacements.
split([sep[, maxsplit]])Returns a list of words/substrings, splitting at the specified separator sep (defaults to whitespace). Optional maxsplit limits the number of splits.
join(iterable)Joins the elements of an iterable (like a list) into a single string, using the string itself as the separator.
find(sub[, start[, end]])Returns the lowest index where substring sub is found within the slice [start:end]. Returns -1 if not found.
index(sub[, start[, end]])Like find(), but raises a ValueError if sub is not found.
count(sub[, start[, end]])Returns the number of non-overlapping occurrences of substring sub within the slice [start:end].
startswith(prefix[, start[, end]])Returns True if the string starts with the specified prefix, False otherwise.
endswith(suffix[, start[, end]])Returns True if the string ends with the specified suffix, False otherwise.
isdigit()Returns True if all characters are digits and there is at least one character.
isalpha()Returns True if all characters are alphabetic and there is at least one character.
isalnum()Returns True if all characters are alphanumeric (letters or numbers) and there is at least one character.
islower()Returns True if all cased characters are lowercase and there is at least one cased character.
isupper()Returns True if all cased characters are uppercase and there is at least one cased character.
isspace()Returns True if all characters are whitespace characters and there is at least one character.
istitle()Returns True if the string is title-cased and there is at least one character.

Example usage:

#!/usr/bin/env python3
text = " Python programming is FUN! "
print(f"Original: '{text}'")
print(f"Stripped: '{text.strip()}'")
print(f"Lower: '{text.lower()}'")
print(f"Upper: '{text.upper()}'")
print(f"Replaced: '{text.replace('FUN', 'Awesome')}'")
print(f"Split: {text.split()}")
words = ['Python', 'is', 'cool']
separator = ' '
print(f"Joined: '{separator.join(words)}'")
print(f"Starts with ' P': {text.startswith(' P')}")
print(f"Ends with '! ': {text.endswith('! ')}")
print(f"Count of 'm': {text.count('m')}")
print(f"Find 'program': {text.find('program')}")