Python Strings, Slicing and Formatting

AI-assistedDrafted with AI assistance and reviewed before publishing; examples are version-pinned. Verify against official docs when in doubt.

Python 3.13

Logs, configuration, API responses, and user input all arrive as text. Most of that text handling comes down to a dozen string operations and one formatting syntax.

Environment

Examples are verified on Python 3.13. Everything below runs in the REPL, so python is enough to follow along.

Creating strings

a = "double quotes"
b = 'single quotes'
c = """a
multi-line string"""

All three are equivalent. Pick one style and stay consistent; most codebases use double quotes.

Two prefixes matter in practice:

path = r"C:\Users\me\notes.txt"   # raw: \n is not a newline
sql = """
SELECT id, name
FROM users
WHERE id = ?
"""

Indexing and slicing

Strings are immutable sequences: you can read characters by position, but not assign to them.

text = "Python"
text[0]     # 'P'
text[-1]    # 'n'
text[0:2]   # 'Py'   (start included, end excluded)
text[::-1]  # 'nohtyP'

text[0] = "p"   # TypeError: 'str' object does not support item assignment

text[::-1] reverses because the step is -1. The same slice syntax works on lists and tuples.

Methods you actually use

Every string method returns a new string; the original is untouched.

s = "  Python,Go,Rust  "

s.strip()                 # 'Python,Go,Rust'
s.split(",")              # ['  Python', 'Go', 'Rust  ']
", ".join(["a", "b"])     # 'a, b'
s.replace("Go", "Java")   # replaces all occurrences
s.lower()                 # 'python,go,rust'

Searching and testing:

"python" in s.lower()       # True
s.strip().startswith("Py")  # True
s.find("Go")                # 8, or -1 when absent
s.count(",")                # 2

find returns -1 when the substring is missing; index raises ValueError instead. Choose based on whether absence is normal or exceptional.

A standard cleanup pipeline:

raw = " Python , Go "
langs = [part.strip() for part in raw.split(",")]
# ['Python', 'Go']

f-strings

Since 3.6, f-strings are the default choice: readable, concise, and fast.

name = "Ada"
score = 92.5
print(f"{name} scored {score}")
# Ada scored 92.5

Anything after the colon is a format spec:

f"{score:.1f}"        # '92.5'   one decimal place
f"{score:>8.1f}"      # '    92.5'  width 8, right aligned
f"{1234567:,}"        # '1,234,567'
f"{0.873:.1%}"        # '87.3%'
f"{name!r}"           # "'Ada'"  calls repr()

Expressions are allowed inside the braces, including calls and conditionals:

f"{len(name)} chars, {'long' if len(name) > 3 else 'short'}"

For quick debugging, = prints the expression next to its value:

print(f"{score=} {name=}")
# score=92.5 name='Ada'

Older styles still appear in existing code:

"%s scored %.1f" % (name, score)
"{} scored {:.1f}".format(name, score)

Both work; new code should use f-strings.

str versus bytes

str holds text, bytes holds raw bytes. Files and sockets deal in bytes, so the conversion is explicit:

text = "café"
data = text.encode("utf-8")   # b'caf\xc3\xa9'
data.decode("utf-8")          # 'café'

Always name the encoding when touching files or network payloads; relying on the platform default produces code that works on your machine and fails elsewhere.

with open("notes.txt", "w", encoding="utf-8") as f:
    f.write("café")

Common mistakes

1. Building strings with + in a loop

result = ""
for part in parts:
    result += part      # allocates a new string every iteration

"".join(parts) is both shorter and faster.

2. Confusing split() with split(",")

"a  b\tc".split()      # ['a', 'b', 'c']  splits on any whitespace, drops empties
"a,,b".split(",")      # ['a', '', 'b']   keeps empty fields

CSV-like data needs the explicit separator.

3. Mixing str and bytes

"abc" + b"def"         # TypeError

Decide at the boundary: decode on input, encode on output.

4. Assuming a method mutates

s.upper()              # discarded
s = s.upper()          # what you meant

5. Formatting floats for money

f"{0.1 + 0.2:.2f}" hides the problem but does not fix the arithmetic. Use decimal.Decimal for currency.

Summary

  • Strings are immutable; methods return new values.
  • Slicing uses start:stop:step, end excluded; [::-1] reverses.
  • strip / split / join cover most text cleanup.
  • f-strings handle formatting; the spec follows the colon.
  • str is text, bytes is data on the wire: convert explicitly with encode / decode.

Next: lists and dictionaries, the two containers you will use most.