Strings support a rich set of operations: concatenation joins strings with +, repetition with * duplicates them, and slicing extracts substrings with s[start:stop:step]. String methods like upper(), lower(), strip(), split(), and join() transform or decompose strings without modifying the original. String formatting (f-strings, format(), or % operator) embeds variable values into text cleanly. These operations enable parsing, cleaning, and generating text data.
Build a simple text-processing program: read a sentence, split it into words, count them, capitalize each word, and rejoin. Practice slicing with both positive and negative indices.
Now that you understand strings as sequences of characters, it's time to learn the toolkit for manipulating them. String operations fall into three broad categories: combining strings, extracting parts of strings, and transforming strings. Mastering these gives you the ability to process text data — which turns out to be one of the most common tasks in programming, from parsing user input to generating reports.
Concatenation joins two strings end-to-end using the `+` operator: `"hello" + " " + "world"` produces `"hello world"`. This works just like addition on numbers, but for text. The `*` operator provides repetition: `"ha" * 3` gives `"hahaha"`. These are intuitive because they extend operators you already know from arithmetic into the domain of text. One critical detail: you cannot concatenate a string and a number directly (`"score: " + 42` raises an error) — you must convert the number to a string first using `str()`, which connects back to the type conversion you've already learned.
Slicing is how you extract substrings. The syntax `s[start:stop]` returns characters from index `start` up to but not including index `stop`. This half-open interval convention matches how `range()` works and prevents off-by-one errors once you internalize it. You can omit `start` to begin at the beginning (`s[:5]`), omit `stop` to go to the end (`s[3:]`), or add a `step` to skip characters (`s[::2]` takes every other character). Negative indices count from the end: `s[-1]` is the last character, and `s[::-1]` reverses the entire string. Slicing never raises an index error — if your bounds exceed the string length, Python quietly returns what's available.
String methods are built-in functions called on string objects using dot notation. `s.upper()` and `s.lower()` change case, `s.strip()` removes leading and trailing whitespace (essential when reading user input), `s.split()` breaks a string into a list of substrings at each space (or a specified delimiter), and `" ".join(words)` does the reverse — gluing a list back into a single string. The crucial thing to remember is that strings are immutable: every method returns a *new* string and leaves the original unchanged. Writing `s.upper()` does nothing unless you capture the result: `s = s.upper()`. This immutability is also why `s.replace("old", "new")` doesn't modify `s` in place — it gives you a fresh string with the substitutions made.
String formatting lets you embed variable values cleanly into text. The modern approach in Python is the f-string: `f"Hello, {name}! You scored {score}."` evaluates the expressions inside curly braces and inserts the results. This replaces clunky concatenation chains and makes your output code much more readable. You can even include expressions and format specifiers inside the braces: `f"{price:.2f}"` formats a float to two decimal places. Together, these operations — concatenation, slicing, methods, and formatting — give you a complete vocabulary for working with text, and they directly prepare you for list operations, since lists share the same indexing and slicing syntax.