A string is a piece of text. Names, sentences, file paths, JSON keys, error messages — every bit of text in a Python program lives in a str.

Creating a string

You can write a string with single or double quotes — both work the same way:

name: str = "Manikandan"
city: str = 'Chennai'

Pick one style and stick to it. Ruff (the formatter we set up) will rewrite all your strings to use double quotes by default.

For longer text, use triple quotes:

description: str = """
This is a longer piece of text.
It can span multiple lines.
Newlines and indentation are preserved as-is.
"""

Joining strings

You can stick two strings together with +:

first: str = "Hello"
second: str = "World"
greeting: str = first + ", " + second + "!"
print(greeting)   # Hello, World!

Or repeat a string with *:

line: str = "-" * 20
print(line)   # --------------------

Length

The built-in len function tells you how many characters are in a string:

name: str = "Python"
print(len(name))   # 6

len also works on lists and dictionaries (we’ll see them in Section 6).

Accessing characters — indexing

You can pick a single character by its position. Positions start at 0, not 1:

word: str = "Python"

print(word[0])   # 'P'
print(word[1])   # 'y'
print(word[5])   # 'n'

Negative numbers count from the end:

print(word[-1])   # 'n'   last character
print(word[-2])   # 'o'   second to last

If you go past the end you get an error:

print(word[10])
IndexError: string index out of range

Slicing — picking a chunk

You can pick a range of characters with [start:end]. The character at end is not included:

word: str = "Python"

print(word[0:3])   # 'Pyt'  characters 0, 1, 2
print(word[2:5])   # 'tho'
print(word[:3])    # 'Pyt'  from start to position 3
print(word[3:])    # 'hon'  from position 3 to end
print(word[:])     # 'Python'  the whole thing (a copy)

You can also use a third number, the step:

print(word[::2])   # 'Pto'    every second character
print(word[::-1])  # 'nohtyP' reversed — a classic Python trick

Strings are immutable

Once a string is created, you cannot change its characters. You can only build a new string:

name = "Python"
name[0] = "J"   # TypeError: 'str' object does not support item assignment

name = "Java"    # this is fine — we're replacing the whole variable

This is a deliberate design choice — it makes strings safe to share between parts of a program.

String methods

A string comes with dozens of built-in methods. The ones you’ll reach for daily:

s: str = "  Hello, Python!  "

print(s.lower())          # '  hello, python!  '
print(s.upper())          # '  HELLO, PYTHON!  '
print(s.strip())          # 'Hello, Python!'  (no spaces)
print(s.replace("Python", "World"))  # '  Hello, World!  '
print(s.split(","))       # ['  Hello', ' Python!  ']
print(s.startswith("  Hello"))  # True
print(s.endswith("!  "))        # True
print("py" in s.lower())        # True

Each method returns a new string — the original s is unchanged.

Escape sequences

Some characters can’t be written directly inside a string. You use a backslash \ to “escape” them:

SequenceMeaning
\nnewline
\ttab
\\a literal backslash
\"a literal double quote inside a "..." string
\'a literal single quote inside a '...' string
print("Line one\nLine two")
print("Name:\tManikandan")
print("She said, \"Python!\"")
print("Path: C:\\Users\\you")
Line one
Line two
Name:	Manikandan
She said, "Python!"
Path: C:\Users\you

Raw strings

When you have a lot of backslashes (file paths, regex patterns), prefix the string with r to turn off escape processing:

path: str = r"C:\Users\you\Documents"
print(path)   # C:\Users\you\Documents

f-strings — formatted strings

The cleanest way to insert variables into a string is an f-string — a regular string prefixed with f:

name: str = "Python"
year: int = 1991
age: int = 2026 - year

print(f"Hello, {name}!")
print(f"You are {age} years old.")
print(f"Math works too: 2 + 2 = {2 + 2}")
Hello, Python!
You are 35 years old.
Math works too: 2 + 2 = 4

Anything inside the { } is a Python expression — variables, arithmetic, function calls, the lot.

Formatting numbers

f-strings can format numbers with a colon-and-spec:

price: float = 9.999

print(f"{price:.2f}")      # 10.00  — 2 decimal places
print(f"{1234567:,}")      # 1,234,567 — thousands separator
print(f"{0.567:.0%}")      # 57% — as a percentage

You don’t need to memorise these. Look them up when you need them.

Older string formatting (for context)

You may see two older styles in old code:

# %-formatting (old)
print("Hello, %s. You are %d years old." % (name, age))

# .format() (older, but cleaner)
print("Hello, {}. You are {} years old.".format(name, age))

These still work. We’ll use f-strings everywhere because they’re the shortest, fastest, and most readable.

What’s next

You can store, slice, and format text. Next we’ll cover type conversion — moving values between int, float, str, and bool.

Toggle theme (T)