Learn Python Strings: Absolute Beginners Tutorial

Strings are one of the most fundamental data types in Python. From storing a username to printing a message on screen, nearly every real-world Python program relies on them. This tutorial walks through everything you need to get started — creating strings, accessing individual characters, slicing ranges, joining strings together, applying built-in methods, and formatting output with f-strings.

Python represents text as a sequence of characters. That sequence can be a single letter, a word, a sentence, or thousands of lines — the behavior is consistent regardless of length. Understanding how Python stores and manipulates strings gives you a foundation that carries into nearly every other topic in the language.

What Is a String in Python?

A string is a sequence of characters enclosed in quotes. Python accepts single quotes, double quotes, or triple quotes. All three produce the same kind of object — the choice is a matter of convenience and readability.

python
greeting = 'Hello, world!'
name = "Kandi"
paragraph = """This spans
multiple lines."""

print(type(greeting))  # <class 'str'>

Triple-quoted strings are useful when a string must span multiple lines, or when it contains both single and double quotes. They are frequently used for docstrings — the documentation blocks placed at the top of functions and classes.

Note

Python strings are immutable. Once created, the characters inside a string cannot be changed in place. Methods that appear to modify a string actually return a brand new string object. The original remains untouched.

Escape characters

Some characters carry special meaning inside a string. A backslash introduces an escape sequence, telling Python to interpret the next character differently rather than as a literal character.

python
print("Line one\nLine two")   # \n = newline
print("col1\tcol2")           # \t = tab
print("She said \"hello\"")   # \" = literal double quote
print("C:\\Users\\kandi")     # \\ = literal backslash

A raw string, prefixed with r, tells Python to treat backslashes as literal characters rather than escape sequences. This is commonly used when writing regular expressions or Windows file paths.

python
path = r"C:\Users\kandi\documents"
print(path)  # C:\Users\kandi\documents

Indexing: Accessing Individual Characters

Python stores each character in a string at a numbered position called an index. Indexing starts at zero, so the first character is always at position 0, not 1. This zero-based convention is common across many programming languages.

P y t h o n [0] [1] [2] [3] [4] [5] [-6] [-5] [-4] [-3] [-2] [-1] 'Python'
Each character in the string 'Python' with its positive index (blue, top) and negative index (yellow, bottom).

To retrieve a character, place its index inside square brackets immediately after the variable name. Python also supports negative indexing: -1 always refers to the last character, -2 to the one before it, and so on. This allows you to count from the end of a string without knowing its length.

python
language = "Python"

print(language[0])   # P  — first character
print(language[2])   # t  — third character
print(language[-1])  # n  — last character
print(language[-2])  # o  — second-to-last

The built-in len() function returns the total number of characters in a string. This is useful for calculating valid index ranges and for looping over each character.

python
word = "Python"
print(len(word))  # 6

# Loop through every character
for char in word:
    print(char)
Pro Tip

Attempting to access an index that does not exist — for example language[10] on a six-character string — raises an IndexError. Always verify the length of a string before using a hardcoded index on unknown input.

code builder click a token to place it

Build the correct Python expression to retrieve the last character of a string called word using negative indexing:

your code will appear here...
word [ -1 ] 0 len
solution: word[-1]

Slicing: Extracting Substrings

Slicing lets you extract a portion of a string by specifying a start and stop index separated by a colon: string[start:stop]. The character at the start index is included. The character at the stop index is excluded — the slice runs up to, but not including, that position.

python
text = "PythonCodeCrack"

print(text[0:6])    # Python     — characters 0 through 5
print(text[6:10])   # Code       — characters 6 through 9
print(text[10:])    # Crack      — from index 10 to the end
print(text[:6])     # Python     — from the beginning to index 5
print(text[-5:])    # Crack      — last five characters

Omitting the start value defaults to 0 (the beginning of the string). Omitting the stop value defaults to the end of the string. Both can be omitted at once to produce a copy of the entire string: text[:].

Step slicing

A third value, the step, controls how many positions to advance between each selected character. The full syntax is string[start:stop:step]. A step of 2 selects every other character. A step of -1 reverses the string — a common technique in Python.

python
alphabet = "abcdefghij"

print(alphabet[0:10:2])  # acegi — every second character
print(alphabet[::-1])    # jihgfedcba — reversed

Slicing versus indexing at a glance

Returns
A single character (a string of length 1)
Use when
You need exactly one character at a known position
Returns
A new string containing the selected range of characters
Use when
You need a substring — a word, prefix, suffix, or any range
Returns
A new string with characters selected at the given step interval
Use when
Reversing a string, sampling every Nth character, or traversing backward

Concatenation and Repetition

Two strings can be joined end-to-end using the + operator. This is called concatenation. The result is a new string — neither of the original strings is modified.

python
first = "Python"
second = "CodeCrack"

combined = first + " " + second
print(combined)  # Python CodeCrack

The * operator repeats a string a given number of times. This is known as repetition and is occasionally useful for building separators or test data.

python
separator = "-" * 30
print(separator)  # ------------------------------

print("ha" * 3)   # hahaha
Watch Out

Python does not automatically convert numbers to strings. Trying to concatenate a string and an integer with + raises a TypeError. Wrap the number in str() first: "Score: " + str(42).

Joining a list of strings efficiently

When you need to combine many strings from a list, using + in a loop is inefficient because it creates a new string object on every iteration. The str.join() method handles this in a single pass and is the preferred approach.

python
words = ["Python", "is", "easy", "to", "learn"]

sentence = " ".join(words)
print(sentence)  # Python is easy to learn

csv_line = ",".join(["Alice", "30", "Engineer"])
print(csv_line)  # Alice,30,Engineer

Built-In String Methods

Python includes a large set of built-in methods that operate on strings. Because strings are immutable, each method returns a new string rather than changing the original. The examples below cover the methods you will encounter most often as a beginner.

"Strings are objects with a rich set of methods." — Python documentation
python
s = "  Hello, Python World!  "

# Case methods
print(s.upper())        # "  HELLO, PYTHON WORLD!  "
print(s.lower())        # "  hello, python world!  "
print(s.title())        # "  Hello, Python World!  "
print(s.swapcase())     # "  hELLO, pYTHON wORLD!  "

# Whitespace
print(s.strip())        # "Hello, Python World!"
print(s.lstrip())       # "Hello, Python World!  "
print(s.rstrip())       # "  Hello, Python World!"

# Search and replace
print(s.strip().replace("Python", "Beginner"))
# "Hello, Beginner World!"

# Finding
print(s.find("Python")) # 9  — index of first match, -1 if not found
print("Python" in s)    # True

# Splitting
words = s.strip().split(", ")
print(words)            # ['Hello', 'Python World!']

# Testing
print("12345".isdigit())    # True
print("hello".isalpha())    # True
print("hello world".isalpha())  # False — space is not alpha

Methods can be chained together. Each call returns a new string, which becomes the target of the next method call. Keep chains readable — three or four methods on one line is often the practical limit before clarity suffers.

python
user_input = "   [email protected]   "
clean = user_input.strip().lower()
print(clean)  # [email protected]
spot the bug click the line that contains the bug

This function is supposed to return the first word of a sentence in uppercase. One line contains a bug. Click the line you think is wrong, then hit check.

1 def first_word_upper(sentence):
2 words = sentence.strip().split()
3 first = words[0]
4 return first.Upper()
5
6 print(first_word_upper("hello world"))
The fix: Change first.Upper() to first.upper(). Python method names are case-sensitive. The built-in string method is .upper() (all lowercase). .Upper() does not exist and raises an AttributeError.

How to Format Strings in Python

Python provides several approaches to embedding variable values inside a string. The three primary methods are f-strings (formatted string literals), the str.format() method, and the older % operator. F-strings, introduced in Python 3.6, are the current recommended approach for their speed and readability.

  1. Use an f-string for simple variable embedding

    Prefix the string literal with f and place the variable or expression directly inside curly braces. Python evaluates the expression at runtime and inserts the result. This is the simplest and most readable option for the majority of situations.

  2. Control number formatting inside f-strings

    Add a format specification after a colon inside the curly braces. For example, {price:.2f} formats the price variable to two decimal places. {count:04d} pads an integer with leading zeros to a width of four digits.

  3. Use str.format() when targeting Python versions below 3.6

    Call .format() on a string that contains {} or named {placeholder} markers. Pass the values to insert as arguments to the method. This approach is compatible with Python 2 and earlier Python 3 releases, but f-strings are preferred in modern code.

  4. Embed expressions, not just variables

    The curly brace syntax inside f-strings accepts any valid Python expression — arithmetic, function calls, conditionals, and more. For example, f"Result: {2 ** 10}" produces "Result: 1024" without needing a separate variable assignment.

  5. Use raw f-strings when combining formatting with backslashes

    When a formatted string must also contain literal backslashes, combine the f and r prefixes: rf"...". This avoids unintended escape sequence processing while still allowing variable embedding through curly braces.

  6. Avoid concatenating with + when formatting multiple values

    Mixing + concatenation with str() conversions to build output strings is verbose and easy to misread. An f-string that references several variables in one literal is almost always clearer and faster.

python
# f-string (Python 3.6+) — recommended
name  = "Kandi"
score = 97.5
print(f"Name: {name}, Score: {score:.1f}%")
# Name: Kandi, Score: 97.5%

# Expressions inside f-strings
width = 80
print(f"{'Centered Title':^{width}}")  # center-aligns text

# str.format()  — compatible with older Python
print("Name: {}, Score: {:.1f}%".format(name, score))

# % operator — legacy, avoid in new code
print("Name: %s, Score: %.1f%%" % (name, score))

Python Strings: Key Points

  1. A string is an immutable sequence of characters. Modifying a string always produces a new string object — the original is never altered.
  2. Indexing uses zero-based integers. The first character is at index 0 and the last is at index -1. Accessing an out-of-range index raises an IndexError.
  3. Slicing with [start:stop:step] extracts a substring. The stop index is always excluded from the result. Omitting start or stop defaults to the beginning or end of the string respectively.
  4. The + operator concatenates strings, the * operator repeats them, and str.join() is the efficient choice when combining many strings from a list.
  5. Built-in methods such as .upper(), .strip(), .replace(), and .split() return new strings and can be chained together.
  6. F-strings are the modern standard for string formatting in Python 3.6 and later. They are faster than str.format() and significantly more readable than % formatting.

With these fundamentals in place, you can handle the vast majority of text manipulation tasks you will encounter as a beginner. From here, the natural next step is to explore regular expressions for pattern matching, or to look at how strings interact with file I/O when reading and writing text files.

check your understanding question 1 of 5

Frequently Asked Questions

A string in Python is a sequence of characters enclosed in single quotes, double quotes, or triple quotes. Strings are immutable, meaning their content cannot be changed after creation, but you can create new strings derived from existing ones.

There is no functional difference. Python treats 'hello' and "hello" as identical string objects. The choice is a matter of style or convenience — double quotes are useful when the string itself contains an apostrophe, and single quotes work well when the string contains double quotes.

No. Python strings are immutable. Once a string is created, its individual characters cannot be changed in place. Methods that appear to modify a string actually return a new string object, leaving the original unchanged.

Use the built-in len() function, passing the string as the argument. For example, len('Python') returns 6. The result is the total number of characters including spaces and punctuation.

String indexing in Python starts at 0. The first character is at index 0, the second at index 1, and so on. Python also supports negative indexing, where -1 refers to the last character, -2 to the second-to-last, and so on.

You can combine strings using the + operator, which is called concatenation. For example, 'Hello' + ' World' produces 'Hello World'. For joining many strings from a list, the str.join() method is more efficient.

An f-string, short for formatted string literal, is a string prefixed with the letter f that allows you to embed Python expressions directly inside curly braces. For example, f'Hello, {name}!' replaces {name} with the value of the variable name at runtime. F-strings were introduced in Python 3.6.

Use the in keyword. For example, 'py' in 'python' returns True. This is case-sensitive, so 'Py' in 'python' returns False. You can also use the str.find() method, which returns the index of the first match or -1 if not found.