Strings
Literals, indexing, slicing, methods, and f-strings
A str in Python 3 is an immutable sequence of Unicode code points. Strings are one of the most-used types in the language—text is everywhere—and Python gives you a rich toolkit for working with them.
Every snippet on this page runs in your browser—no setup required.
Real-world context: Text is everywhere
Strings show up in almost every program:
- Web apps: HTTP headers, JSON payloads, URLs, query parameters, HTML templates.
- Data pipelines: CSV rows, log lines, file paths, column names.
- Automation scripts: command output, configuration files, environment variables.
- Games: dialogue, item names, save files.
Understanding strings—indexing, slicing, formatting, and the immutability gotcha—is essential to productive Python programming.
String literals
There are four ways to write a string literal. They're all equivalent at the value level—pick whichever avoids backslash escapes.
Escape sequences
| Sequence | Meaning |
|---|---|
\\n | newline |
\\t | tab |
\\\\ | backslash |
\\', \\" | quote of that kind |
\\u00e9 | Unicode code point (here, é) |
\\xff | hex byte |
Raw strings
Prefix a literal with r to disable escape processing. Useful for regex patterns and Windows paths.
Indexing and slicing
Strings are sequences, so they support indexing (s[i]) and slicing (s[start:stop:step]). Indices are zero-based; negative indices count from the end.
Slicing never raises IndexError, even with out-of-range bounds. It just returns whatever overlaps.
Unicode and len(): the emoji surprise
In Python 3, len(s) returns the number of Unicode code points, not bytes. Most characters are one code point, but some emoji and complex scripts can surprise you:
print(len("👍")) # 1 (single code point)
print(len("👨👩👧👦")) # 7 (family emoji is a sequence of code points + zero-width joiners)If you need byte length, encode first: len(s.encode("utf-8")).
Strings are immutable
You cannot mutate a string in place. Methods like upper(), replace(), and strip() return new strings.
Immutability gotcha
Because strings are immutable, repeatedly concatenating with += in a loop is O(n²)—each operation creates a new string and copies everything.
Bad:
result = ""
for i in range(1000):
result += str(i) # creates a new string each timeGood:
parts = []
for i in range(1000):
parts.append(str(i))
result = "".join(parts)str.join() is the idiomatic way to build a string from many pieces.
Common methods
A selection of methods you'll use constantly:
Formatting: f-strings (the killer feature)
f-strings (Python 3.6+) are the modern, recommended way to build strings. Put any expression inside { ... }.
f-string format mini-language
The part after : in {value:format} is a powerful mini-language:
.Nf— N decimal places for floats>width— right-align in width<width— left-align^width— center,— thousands separator0Nf— zero-pad%— multiply by 100 and add percent sign
Full spec: Format Specification Mini-Language.
Other formatting styles you'll see in older code:
Concatenation and repetition
Bytes vs strings
str holds Unicode code points; bytes holds raw 8-bit values. Use .encode() to go from str to bytes and .decode() to go back. The default codec is UTF-8.
str vs bytes: a common source of bugs
File I/O, network I/O, and many libraries return bytes, not str. If you try to concatenate str and bytes, you'll get a TypeError. Always decode bytes to strings before working with text:
response = b"Hello" # from a network request
# Bad: "Greeting: " + response # TypeError
# Good: "Greeting: " + response.decode("utf-8")Challenges
Define a function format_name(first, last) that returns the name in the form "Last, First", with both names title-cased and any surrounding whitespace stripped. For example, format_name(" ada", "LOVELACE ") should return "Lovelace, Ada".
Write a function is_palindrome(s) that returns True if s reads the same forward and backward, ignoring case and any non-alphanumeric characters. For example, "A man, a plan, a canal: Panama" is a palindrome.
Write a function slugify(text) that converts a string to a URL-friendly "slug": lowercase, spaces replaced with hyphens, only alphanumerics and hyphens allowed. For example, slugify("Hello World!") returns "hello-world".
Check your understanding
What does "abcdef"[1:5:2] evaluate to?
"bcd"
"bd"
"ace"
An IndexError
Which statement about string immutability is true?
s.upper() changes s to uppercase.
You can mutate a string by assigning to an index: s[0] = "H".
To "change" a string, you must rebind the variable to a new string.
Immutability means you can't create new strings.
What does f"{123:05d}" produce?
"123"
"00123"
"123.00"
An error
Which approach builds a string from a list of 1000 items without the O(n²) cost of repeated concatenation?
result = ""; for x in items: result += str(x)
result = sum(str(x) for x in items)
result = "".join(str(x) for x in items)
result = "".add(str(x) for x in items)
Next: booleans, comparisons, and Python's short-circuiting logical operators.