String

Learn about strings in Python.

Ali Berro

By Ali Berro

15 min read Section
From: Python Fundamentals: From Zero to Hero

String

A string is an immutable sequence of characters. Strings support all common sequence operations. In Python, strings can be created using single quotes ', double quotes ", or triple quotes '''/""" for multiline strings.

single_quotes = 'Hello world'
double_quotes = "Hello world"
triple_quotes = """This is a
multiline string
spanning several lines"""
triple_quotes_2 = '''This is
another multiline string
spanning several lines'''

Common Sequence Operations

Strings are sequences, which means they support common sequence operations that work with other sequence types like lists and tuples. These operations include:

  • Membership: Check if a character or substring exists
  • Length: Get the number of characters
  • Minimum and Maximum: Find the smallest and largest characters (by ASCII/Unicode value)
  • Counting: Count the number of occurrences of a character or substring
  • Searching: Find the index of a character or substring
  • Indexing: Access characters by their position
  • Slicing: Extract portions of the string
  • Concatenation: Combine strings
  • Repetition: Repeat strings

Indexing, Slicing, and Immutability

Strings support indexing and slicing just like lists and tuples. Characters can be accessed using positive indices (starting at 0) or negative indices (counting from the end), and strings can be sliced using the same [start:stop:step] syntax. However, strings are immutable: their contents cannot be changed after creation.

text = "Hello"
print(text[0]) # H
print(text[-1]) # o
print(text[1:4]) # ell
print(text[::2]) # Hlo
text[0] = "h" # TypeError: 'str' object does not support item assignment

Note

Since there is no separate character type in Python, indexing a string produces another string of length 1, not a character type.

Warning

Since strings are immutable, characters cannot be modified, added, or deleted. Slicing creates a new string, leaving the original unchanged.

String Concatenation

Strings can be concatenated using the + operator or by placing them adjacent to each other:

# Using + operator
greeting = "Hello" + " " + "World" # "Hello World"
# Adjacent strings (implicit concatenation)
text = "ABC" "DEF" # "ABCDEF"
text = "Hello" " " "World" # "Hello World"

Tip

Adjacent string literals are automatically concatenated by Python, which is useful for breaking long strings across multiple lines without using +.

Escape Characters

Escape characters allow the inclusion of special characters in strings that would otherwise be difficult or impossible to represent:

CharacterDescription
\nNewline
\tTab
\rCarriage return
\\Backslash
\'Single quote
\"Double quote
\bBackspace
text = "Hello\nWorld" # Prints on two lines
path = "C:\\Users\\Name" # Escaped backslashes
quote = "He said \"Hello\"" # Escaped quotes

Raw Strings

Raw strings (prefixed with r or R) treat backslashes as literal characters, which is useful for file paths, regular expressions, and other cases where escape sequences should not be interpreted:

# Regular string
text = "Hey\nHow\tare\ryou?" # Escape sequences are interpreted
# Raw string
raw_text = r"Hey\nHow\tare\ryou?" # Escape sequences are literal
print(raw_text) # Prints: Hey\nHow\tare\ryou?
# Useful for file paths
path = r"C:\Users\Name\Documents" # No need to escape backslashes

Looping, Membership, and Operators

Strings support the same iteration and operator behaviors as lists and tuples: you can loop through strings using for or while loops, check membership with in and not in, and use identity operators is and is not. The assignment operator works the same way, but since strings are immutable, assigning a string to multiple variables is safe.

text = "Hello"
# Looping
for char in text:
print(char)
for i in range(len(text)):
print(i, ":", text[i])
i = 0
while i < len(text):
print(text[i])
i += 1
# Membership (works with substrings too)
print("H" in text) # True
print("ell" in text) # True
print("xyz" not in text) # True

Notable String Methods

Strings have many useful methods. Here are some of the most commonly used:

Searching and Counting

  • count(substring): Returns the number of occurrences of substring in the string.
  • find(substring): Returns the index of the first occurrence of substring. Returns -1 if not found.
  • index(substring): Similar to find(), but raises a ValueError if not found.
  • startswith(prefix): Returns True if the string starts with prefix.
  • endswith(suffix): Returns True if the string ends with suffix.
text = "Hello World"
print(text.count("l")) # 3
print(text.find("World")) # 6
print(text.find("Python")) # -1
print(text.index("World")) # 6
print(text.startswith("Hello")) # True
print(text.endswith("World")) # True

Case Conversion

  • lower(): Returns a copy of the string in lowercase.
  • upper(): Returns a copy of the string in uppercase.
  • capitalize(): Returns a copy with the first character capitalized.
  • title(): Returns a copy with the first letter of each word capitalized.
text = "hello WORLD"
print(text.lower()) # "hello world"
print(text.upper()) # "HELLO WORLD"
print(text.capitalize()) # "Hello world"
print(text.title()) # "Hello World"

Splitting and Joining

  • split(sep=None): Returns a list of words in the string, using sep as the delimiter. If sep is not specified, splits on whitespace.
  • join(iterable): Concatenates the elements of iterable with the string as a separator. All elements must be strings.
text = "apple,banana,cherry"
fruits = text.split(",") # ['apple', 'banana', 'cherry']
words = "Hello World Python"
word_list = words.split() # ['Hello', 'World', 'Python']
# Joining
separator = ", "
result = separator.join(fruits) # "apple, banana, cherry"

String Formatting

Python provides several ways to format strings with variables.

Using .format() Method

The .format() method allows the insertion of values into placeholders marked by curly braces {}. There are three ways to specify which values go into which placeholders:

Automatic Field Specification

With automatic field specification, empty curly braces {} are used and Python automatically fills them in order based on the arguments passed to .format(). The first {} gets the first argument, the second {} gets the second argument, and so on.

txt = "My name is {}, and I am {} years old"
print(txt.format("Ali", 25)) # "My name is Ali, and I am 25 years old"
txt = "Your total is {}, it becomes {} after discount"
print(txt.format(50, 42)) # "Your total is 50, it becomes 42 after discount"

Manual Field Specification with Indices

With manual field specification, indices inside the curly braces (e.g., {0}, {1}, {2}) are used to explicitly control which argument goes where. This allows arguments to be reused or their order to be changed.

txt = "I have {0} apples and {1} oranges. Total: {0} + {1} = {2}"
print(txt.format(5, 3, 8)) # "I have 5 apples and 3 oranges. Total: 5 + 3 = 8"
txt = "You have ordered {0} items, {0} items, {0} ITEMS, don't be a Karen!"
print(txt.format(50)) # "You have ordered 50 items, 50 items, 50 ITEMS, don't be a Karen!"

Named Fields

With named fields, descriptive names inside the curly braces (e.g., {name}, {age}) are used and the values are passed as keyword arguments to .format(). This makes the code more readable and self-documenting.

txt = "My name is {name}, and I am {age} years old"
print(txt.format(name="Ali", age=25)) # "My name is Ali, and I am 25 years old"
txt = "I have ordered {items} items, you charged me {total}, and the total is {discount}"
print(txt.format(total=50, discount=42, items=10)) # "I have ordered 10 items, you charged me 50, and the total is 42"

Formatted String Literals (f-strings)

F-strings provide a more concise and readable way to format strings by prefixing the string with f or F and placing expressions directly inside curly braces, which is similar to the named fields in the .format() method:

name = "Ali"
age = 25
txt = f"My name is {name}, and I am {age} years old"
print(txt) # "My name is Ali, and I am 25 years old"
# Can include expressions
x = 10
y = 20
result = f"The sum of {x} and {y} is {x + y}" # "The sum of 10 and 20 is 30"

Tip

F-strings are generally preferred over .format() for their readability and performance, but .format() is still useful for dynamic format strings or when format specifications need to be reused.

String as a Sequence

Strings are sequences, so let’s see all the sequence operations in one example:

text = "Hello"
print(text) # Hello
print(len(text)) # 5
print(min(text)) # H (by ASCII value)
print(max(text)) # o (by ASCII value)
print("e" in text) # True
print("z" in text) # False
print(text.count("l")) # 2
print(text.find("l")) # 2
print(text[1::2]) # el
print(text * 2) # HelloHello
print(text + " World") # Hello World

Why Are Strings Immutable?

There are several important reasons why strings are immutable in Python:

  1. Performance: Immutable strings allow Python to allocate fixed space at creation time, knowing the string will never change. This enables optimizations like string interning.

  2. Elemental Nature: Strings are considered as “elemental” as numbers. Just as the number 1 will always be 1, a string like "Hello" should always be "Hello". We don’t change values, we create new ones.

  3. Hashability: Since strings are immutable, they can be used as dictionary keys and set elements.

Exercises

Exercise 1: Print each character on a new line

Write a program that reads a string and prints each character on a new line.

Print Characters

Checks: 0 times
Answer:
text = input()
for char in text:
print(char)

Exercise 2: Count vowels in a string

Write a program that reads a string and counts the number of vowels (a, e, i, o, u) in it. Count both uppercase and lowercase vowels.

Count Vowels

Checks: 0 times
Answer:
text = input()
vowels = "aeiouAEIOU"
count = 0
for char in text:
if char in vowels:
count += 1
print(count)

Exercise 3: Reverse a string

Write a program that reads a string and prints it in reverse order (without using slicing or the reversed() function).

Reverse String

Checks: 0 times
Answer:
text = input()
reversed_text = ""
for i in range(len(text) - 1, -1, -1):
reversed_text += text[i]
print(reversed_text)

Exercise 4: Check if string is a palindrome

Write a program that reads a string and prints "Yes" if it is a palindrome (reads the same forwards and backwards), otherwise prints "No". Consider only alphanumeric characters and ignore case.

Palindrome Check

Checks: 0 times
Answer:
text = input().lower()
reversed_text = ""
for i in range(len(text) - 1, -1, -1):
reversed_text += text[i]
if text == reversed_text:
print("Yes")
else:
print("No")

Exercise 5: Count words in a string

Write a program that reads a string and counts the number of words in it. Words are separated by spaces.

Count Words

Checks: 0 times
Answer:
text = input().strip()
if text == "":
print(0)
else:
words = text.split()
print(len(words))

Exercise 6: Replace all occurrences of a substring

Write a program that reads a string, then reads a substring to find, then reads a substring to replace it with, and prints the string with all occurrences of the first substring replaced by the second substring (without using the replace() method).

Replace Substring

Checks: 0 times
Answer:
text = input()
old = input()
new = input()
result = ""
i = 0
while i < len(text):
if text[i:i+len(old)] == old:
result += new
i += len(old)
else:
result += text[i]
i += 1
print(result)

Exercise 7: Check if string starts with a prefix

Write a program that reads a string and a prefix, then prints "Yes" if the string starts with the prefix, otherwise prints "No" (without using the startswith() method).

Check Prefix

Checks: 0 times
Answer:
text = input()
prefix = input()
if len(prefix) > len(text):
print("No")
else:
match = True
for i in range(len(prefix)):
if text[i] != prefix[i]:
match = False
break
if match:
print("Yes")
else:
print("No")

Exercise 8: Convert string to uppercase without using upper()

Write a program that reads a string and converts all lowercase letters to uppercase, printing the result (without using the upper() method).

To Uppercase

Checks: 0 times
Answer:
text = input()
result = ""
for char in text:
if 'a' <= char <= 'z':
result += chr(ord(char) - ('a' - 'A'))
else:
result += char
print(result)

Exercise 9: Remove all spaces from a string

Write a program that reads a string and removes all spaces from it, then prints the result.

Remove Spaces

Checks: 0 times
Answer:
text = input()
result = ""
for char in text:
if char != " ":
result += char
print(result)

Exercise 10: Join list of strings with a separator

Write a program that reads the number of strings, then reads each string, then reads a separator string, and prints all the strings joined together with the separator between them (without using the join() method).

Join Strings

Checks: 0 times
Answer:
n = int(input())
strings = []
for i in range(n):
strings.append(input())
separator = input()
result = ""
for i in range(len(strings)):
result += strings[i]
if i < len(strings) - 1:
result += separator
print(result)

Exercise 11: Format string with variables

Write a program that reads a name and an age, then prints the formatted string: "My name is {name} and I am {age} years old" using f-string formatting.

Format String

Checks: 0 times
Answer:
name = input()
age = input()
result = f"My name is {name} and I am {age} years old"
print(result)

Exercise 12: Count occurrences of each character

Write a program that reads a string and counts how many times each character appears. Print each character and its count on a separate line, in the order they first appear in the string.

Character Count

Checks: 0 times
Answer:
text = input()
seen = []
for char in text:
if char not in seen:
count = text.count(char)
print(f"{char} {count}")
seen.append(char)

Course Progress

Section 24 of 61

Back to Course