Python Strings Basics: Text, Quotes, Indexing, and Common Operations
Strings are Python’s text values. You use them to store names, messages, file paths, and almost any human-readable data. A string is an ordered sequence of characters, so you can print it, combine it, measure it, and pick out individual characters by position.
Difficulty: Beginner
Helpful to know first: basic Python variables, how print() works, and the idea of zero-based indexing.
How Python Stores Text in a String
A Python string is a value made of characters. You create one by putting text inside quotes. Python does not treat the quotes as part of the text; the quotes only mark where the string starts and ends.
Strings can hold letters, digits, spaces, punctuation, and symbols. They are a built-in type, so you do not need to import anything to use them.
first_name = "Ada"
greeting = 'Hello, world!'
print(first_name)
print(greeting)
# Output:
# Ada
# Hello, world!This shows the main idea: a string is just text stored in a variable. The choice between single quotes and double quotes does not change the value.
Single quotes and double quotes
Python lets you use either ' or " for the outer quotes. Many programmers pick one style and stay consistent.
city = 'Paris'
language = "Python"
print(city)
print(language)
# Output:
# Paris
# PythonUse whichever quote style makes the string easiest to read. If the text contains an apostrophe, double quotes often look cleaner. If the text contains double quotes, single quotes often look cleaner.
Strings with quotes inside them
When the text itself contains a quote character, you can either choose the other quote style or escape the inner quote with a backslash.
message_one = "I'm learning Python."
message_two = 'She said, "Hello!"'
print(message_one)
print(message_two)
# Output:
# I'm learning Python.
# She said, "Hello!"The backslash tells Python to treat the next character as part of the string instead of ending it early.
Working with String Characters One by One
Strings are ordered. That means each character has a position, starting at index 0. The first character is at index 0, the second is at index 1, and so on.
You can read one character with indexing. You can read a group of characters with slicing.
Reading a single character by index
Indexing gives you one character from a string. Because Python starts counting at zero, the first character is not at position 1.
word = "Python"
print(word[0])
print(word[3])
# Output:
# P
# hThis is useful when you need a specific letter, such as the first character of a code, the last letter of a word, or a check digit in a formatted value.
Using negative indexes
Negative indexes count from the end of the string. -1 is the last character, -2 is the second-to-last character, and so on.
name = "Maya"
print(name[-1])
print(name[-2])
# Output:
# a
# yNegative indexing is common when you want the last character without first measuring the string.
Slicing out part of a string
A slice returns a substring. The syntax is text[start:stop]. The start index is included, but the stop index is excluded.
word = "Python"
print(word[0:2])
print(word[2:6])
# Output:
# Py
# thonBecause the stop index is not included, word[0:2] returns the first two characters, not three. That rule is one of the most important string basics to remember.
Combining Strings and Building Text
Strings are often combined to create messages, labels, and output. Python gives you several ways to do that, and they are not all interchangeable.
Using the plus operator to join strings
You can join two strings with +. This is called concatenation.
first = "Ada"
last = "Lovelace"
full_name = first + " " + last
print(full_name)
# Output:
# Ada LovelaceThis works well when you are building text from a few pieces. If you are joining many pieces, other methods can be easier to read.
Using f-strings for readable formatting
An f-string lets you place expressions inside a string. It is usually the clearest way to combine text and values.
name = "Ada"
score = 98
print(f"{name} scored {score}.")
# Output:
# Ada scored 98.Inside the curly braces, Python evaluates the expression and inserts the result into the string.
Converting non-strings before combining them
Python does not let you join a string directly with a number using +. You must convert the number first, or use an f-string.
age = 20
print("Age: " + str(age))
print(f"Age: {age}")
# Output:
# Age: 20
# Age: 20This is a common beginner fix for the error TypeError: can only concatenate str (not "int") to str. The message means Python found a string and a number, but + for strings only works with strings on both sides.
How String Length and Immutability Affect Your Code
The length of a string is the number of characters it contains. You can get that count with len(). Strings are also immutable, which means you cannot change one character in place.
Measuring string length
len() counts every character, including spaces and punctuation.
text = "Hi!"
print(len(text))
# Output:
# 3That count includes the letters H and i and the punctuation mark !.
Why strings cannot be changed in place
If you try to replace one character directly, Python raises an error because strings do not support item assignment.
word = "cat"
# word[0] = 'b' # TypeError: 'str' object does not support item assignment
new_word = "b" + word[1:]
print(new_word)
# Output:
# batInstead of editing the original string, you build a new one from pieces. This immutability matters because it affects how you think about updates and performance.
A string may look like a list of characters, but it is not a list. You can read characters by position, but you cannot change them one by one.
Realistic Examples of Python Strings
Creating a display label
Strings often combine user input or variable values into a readable label. An f-string keeps this simple.
product = "Notebook"
price = 4.5
print(f"{product}: ${price}")
# Output:
# Notebook: $4.5This pattern appears in menus, receipts, logs, and debug output.
Checking the first letter of a string
You can use indexing to inspect part of a string before making a decision.
filename = "report.txt"
if filename[-4:] == ".txt":
print("Text file")
else:
print("Not a text file")
# Output:
# Text fileThis example uses a slice to compare the ending of the filename. The slice works even though the string is longer than the part you need.
Removing extra spaces at the edges
Strings often come with leading or trailing spaces from user input. The strip() method removes those edge spaces.
raw_name = " Ada "
clean_name = raw_name.strip()
print(f"[{raw_name}]")
print(f"[{clean_name}]")
# Output:
# [ Ada ]
# [Ada]This is common when you read text from the keyboard, a file, or a web form.
How Strings Behave in Python
Three details cause many beginner mistakes: zero-based indexing, slicing rules, and immutability. These are not small details; they shape how you work with text in Python.
Indexing starts at zero
If a string has five characters, the valid indexes are 0 through 4. Asking for index 5 is out of range.
text = "hello"
# print(text[5]) # IndexError: string index out of rangeThat error means there is no character at that position. It is one of the most common beginner string errors.
Slices can go past the end safely
Unlike indexing, slicing does not crash when the stop position is too large. Python just returns as much as it can.
text = "hello"
print(text[2:100])
# Output:
# lloThis is useful when you are not sure how long the text is. Indexing and slicing look similar, but they are not equally strict.
Strings are immutable
When you create a new string from an old one, Python makes a new object. The old one stays the same.
text = "hello"
upper_text = text.upper()
print(text)
print(upper_text)
# Output:
# hello
# HELLOThis is why string methods usually return a new string instead of changing the original one.
Predict the Output
String indexes are zero-based
What does this print?
word = "Python"
print(word[1])
print(word[4])Show answer
It prints y and then o. The first character is at index 0, so index 1 is y. Index 4 is the fifth character, which is o.
# Output:
# y
# oStrings do not change in place
What happens here?
text = "cat"
copy = text
copy = "b" + copy[1:]
print(text)
print(copy)Show answer
It prints cat and then bat. The variable copy first points to the same string as text, but the reassignment creates a new string for copy. The original text value does not change.
# Output:
# cat
# batCommon Mistakes
Using the wrong quote style inside a string
Beginner code often breaks when the text contains an apostrophe or quotation mark and the outer quotes do not match the content.
Problem: Python thinks the string ends too early, so the code no longer parses as one string.
# This raises a SyntaxError
message = 'I'm learning Python.'
print(message)Fix: Use the other quote style or escape the inner quote.
message_one = "I'm learning Python."
message_two = 'I\'m learning Python.'
print(message_one)
print(message_two)The corrected versions work because the string delimiters and the text inside them no longer conflict.
Trying to change one character directly
Strings look editable, but they are immutable. A direct assignment to one character fails.
Problem: Python rejects item assignment on a string because strings cannot be edited in place.
word = "cat"
word[0] = "b"
print(word)Fix: Build a new string from the part you want to keep and the part you want to add.
word = "cat"
word = "b" + word[1:]
print(word)The fixed version works because it creates a new string instead of trying to edit the old one.
Adding a number to a string without converting it
Python does not automatically turn numbers into text when you use + with strings.
Problem: The left side is a string, but the right side is an integer, so concatenation fails.
age = 20
print("Age: " + age)Fix: Convert the number with str() or use an f-string.
age = 20
print("Age: " + str(age))
print(f"Age: {age}")The corrected code works because both pieces are text by the time Python combines them.
Going past the end with indexing
Beginners often ask for a character position that does not exist, especially when they forget that indexing starts at zero.
Problem: The string has five characters, so index 5 is outside the valid range 0 to 4.
text = "hello"
print(text[5])Fix: Use a valid index or a slice if you want a section of the string.
text = "hello"
print(text[4])
print(text[4:])The corrected code works because both expressions stay within the valid range of the string.
Find the Bug
Find the bug in this short program. It is trying to show the first and last letters of a name, but one line is wrong.
name = "Maya"
first_letter = name[1]
last_letter = name[-1]
print(first_letter, last_letter)Show answer
The bug is the index for first_letter. Python counts from zero, so name[1] is the second character, not the first.
Fixed code:
name = "Maya"
first_letter = name[0]
last_letter = name[-1]
print(first_letter, last_letter)
# Output:
# M aThe fixed version works because 0 is the first character in a Python string.
When to Use Strings, and When to Use Something Else
Use strings when the data is text. Use another type when the data is naturally numeric, structured, or ordered in a way that is not text.
| Use this | When it fits | Example |
|---|---|---|
| str | Human-readable text, labels, messages, names, and file names | "Python 3.12" |
| int | Whole numbers you want to calculate with | 42 |
| list | Multiple separate values you may want to change or reorder | ["red", "green", "blue"] |
| bytes | Raw binary data, file contents, and network data | b"hello" |
Strings are the right choice when the meaning is text, even if the text contains digits. A ZIP code, product code, or phone number is often a string because you usually do not calculate with it.
Strings versus lists of characters
Sometimes beginners expect strings to behave like lists. They do share some ideas, such as indexing and length, but strings are fixed text values, while lists are mutable collections. If you need to replace or remove individual items often, a list may be a better fit during processing.
A common pattern is to keep text as a string for display and input, then split it into parts or convert pieces to numbers only where needed.
Strings versus numbers
Use a string when the exact characters matter. Use a number when arithmetic matters.
| If you need to... | Use | Why |
|---|---|---|
| Add, subtract, multiply, or compare quantities | int or float | Numbers support math directly |
| Keep formatting exactly as typed | str | Leading zeros, spaces, and symbols stay intact |
Predict the Output
Why slicing is different from indexing
What does this print?
text = "hello"
print(text[1:4])Show answer
It prints ell. The slice starts at index 1 and stops before index 4, so it includes characters at indexes 1, 2, and 3.
# Output:
# ellTry It Yourself
- Create a variable named title with the value "Python".
- Print the first letter.
- Print the last two letters.
- Print the length of the string.
Expected output:
P
on
6Hint: Use title[0], title[-2:], and len(title).
Show solution
title = "Python"
print(title[0])
print(title[-2:])
print(len(title))
# Output:
# P
# on
# 6Summary
- A Python string is text inside quotes, such as "Ada" or 'Python'.
- Strings are ordered, so you can use indexes and slices to read parts of them.
- Python counts from zero, so the first character is at index 0.
- Strings are immutable, so you build a new string instead of changing one character in place.
- Use +, str(), and f-strings to combine text and values safely.
- len() counts characters, including spaces and punctuation.
Next, learn Python string methods such as strip(), lower(), replace(), and split().