Python Strings: Everything You Can Do With Text
Slicing, cleaning, searching, splitting and formatting. Plus the one rule that explains most string bugs.
Hey again!
Time to settle a debt.
For three posts now, I’ve been sneaking things like .strip(), .title() and .split() into the mini projects and moving on as if they were obvious. In the contact book, the playlist matcher, even the to-do list. Some of you probably copied them, saw that they worked, and quietly wondered what they actually do.
Today we fix that properly.
Text is everywhere in real programs. Usernames, emails, search boxes, file names, messages, web pages. If you can work with strings confidently, a huge number of everyday problems suddenly become easy.
What You’ll Master Today
By the end of this post, you’ll be able to:
- Slice and index strings (you already know how, you just don’t know it yet)
- Understand why string methods “don’t work” the first time
- Clean messy text with
strip(),lower()and friends - Search inside text with
in,find(),count()andreplace() - Break text apart with
split()and glue it back withjoin() - Format numbers and tables neatly with f-strings
- Build a Text Analyzer
Prerequisites: Everything so far, especially Lists, Loops and Dictionaries.
Part 1: A String Is Just a Sequence
Here’s some good news. You already know most of this.
A string is a sequence of characters, and it behaves a lot like a list. Indexing, negative indexing, slicing, len() and in all work exactly the way they did in the lists post:
word = "Python"
print(word[0])
print(word[-1])
print(word[0:3])
print(word[::-1])
print(len(word))
print("th" in word)
# Output:
# P
# n
# Pyt
# nohtyP
# 6
# TrueAnd you can loop over a string, one character at a time:
for letter in "Hi!":
print(letter)
# Output:
# H
# i
# !Part 2: The One Rule — Strings Never Change
This is the rule I mentioned in the subtitle. Strings are immutable, just like tuples:
word = "Python"
word[0] = "J"
# TypeError: 'str' object does not support item assignmentNow here’s where beginners get stuck. Look at this:
name = "ajay"
name.upper()
print(name)
# Output:
# ajayWait, why is it still lowercase?
Because .upper() can't change the original string. Strings never change. Instead, it returns a new string, and here we threw that new string away.
To keep the result, save it:
name = "ajay"
name = name.upper()
print(name)
# Output:
# AJAYBurn this into your memory: string methods give you a new string. They never change the old one. Once this clicks, a whole category of “why isn’t my code working?” bugs disappears.
Part 3: Changing Case and Cleaning Up
text = "hello WORLD"
print(text.upper())
print(text.lower())
print(text.title())
print(text.capitalize())
# Output:
# HELLO WORLD
# hello world
# Hello World
# Hello worldlower() is the one you'll use most. It's how you compare text without caring about capitals:
answer = "YES"
if answer.lower() == "yes":
print("Great, let's go!")
# Output:
# Great, let's go!Removing extra spaces
When people type into a form, they add spaces by accident all the time. strip() removes spaces (and newlines) from both ends:
raw = " priya@example.com "
print(f"[{raw}]")
print(f"[{raw.strip()}]")
print(f"[{raw.lstrip()}]")
print(f"[{raw.rstrip()}]")
# Output:
# [ priya@example.com ]
# [priya@example.com]
# [priya@example.com ]
# [ priya@example.com]I put brackets around the text so you can actually see the spaces. lstrip() cleans only the left side, rstrip() only the right.
Get Ajay Narayan’s stories in your inbox
Join Medium for free to get updates from this writer.
And because each method returns a string, you can chain them. That’s exactly what we did in the contact book:
name = " aLIce "
print(name.strip().title())
# Output:
# AliceRead it left to right: take the name, strip the spaces, then make it title case.
Part 4: Searching Inside Text
email = "priya@example.com"
print("@" in email)
print(email.find("@"))
print(email.find("#"))
print(email.count("e"))
print(email.startswith("priya"))
print(email.endswith(".com"))
# Output:
# True
# 5
# -1
# 2
# True
# Trueinanswers yes or nofind()tells you where something is (its index), or-1if it isn't therecount()counts how many times something appearsstartswith()andendswith()check the beginning and the end
Replacing text
message = "I love Java. Java is great."
new_message = message.replace("Java", "Python")
print(new_message)
print(message)
# Output:
# I love Python. Python is great.
# I love Java. Java is great.Notice the original message didn't change. Same rule as before: you get a new string back.
Checking what’s inside
These are perfect for validating user input:
print("2026".isdigit())
print("12a".isdigit())
print("Ajay".isalpha())
print("Ajay Narayan".isalpha())
# Output:
# True
# False
# True
# FalseThat last one is False because a space is not a letter. Small detail, but it will save you one day.
Part 5: Split and Join
split() breaks a string into a list. By default, it splits on spaces:
sentence = "Python is really fun"
words = sentence.split()
print(words)
print(len(words))
# Output:
# ['Python', 'is', 'really', 'fun']
# 4You can split on anything you like. This is how the playlist matcher read comma-separated songs:
data = "apple,banana,cherry"
fruits = data.split(",")
print(fruits)
# Output:
# ['apple', 'banana', 'cherry']join() does the opposite. It glues a list of strings back together, with whatever separator you choose:
fruits = ["apple", "banana", "cherry"]
print(", ".join(fruits))
print(" -> ".join(fruits))
# Output:
# apple, banana, cherry
# apple -> banana -> cherryThe syntax looks backwards at first: the separator comes first, then .join(), then the list. Think of it as "use this glue to join these pieces."
Part 6: f-Strings, Properly
You’ve been using f-strings since the variables post. Here’s what else they can do.
Formatting numbers
price = 1234.5
score = 0.875
print(f"{price:.2f}")
print(f"{price:,.2f}")
print(f"{score:.1%}")
# Output:
# 1234.50
# 1,234.50
# 87.5%.2fmeans "two decimal places",adds thousands separators.1%turns 0.875 into a percentage with one decimal place
Lining things up
You can give a value a fixed width and choose how to align it. < means left, > means right:
items = [("Coffee", 120), ("Sandwich", 85.5), ("Juice", 60)]
for name, price in items:
print(f"{name:<10}{price:>8.2f}")
# Output:
# Coffee 120.00
# Sandwich 85.50
# Juice 60.00{name:<10} means "put the name in a space 10 characters wide, aligned left". {price:>8.2f} means "8 characters wide, aligned right, two decimals". Suddenly your terminal output looks like a proper receipt.
Special characters
A backslash inside a string starts a special character:
print("Line one\nLine two")
print("Name:\tAjay")
print("She said \"hello\"")
# Output:
# Line one
# Line two
# Name: Ajay
# She said "hello"\n is a new line, \t is a tab, and \" lets you put a double quote inside a double-quoted string.
Real-World: Username Checker
Let’s combine a few of these into something you’d find in an actual sign-up form:
def check_username(username):
username = username.strip()
if len(username) < 4:
return "Too short (minimum 4 characters)"
if not username.isalnum():
return "Only letters and numbers allowed"
if username[0].isdigit():
return "Can't start with a number"
return "Looks good!"
print(check_username(" ajay123 "))
print(check_username("aj"))
print(check_username("ajay_n"))
print(check_username("7ajay"))
# Output:
# Looks good!
# Too short (minimum 4 characters)
# Only letters and numbers allowed
# Can't start with a numberisalnum() is new: it checks that every character is a letter or a number. The underscore in "ajay_n" isn't either, so it fails.
Mini Project: Text Analyzer
Paste in any paragraph and get a little report about it. This one uses strings, lists, loops, a dictionary and a function that returns a tuple. Basically, the whole series so far.
def clean_words(text):
words = []
for word in text.lower().split():
word = word.strip(".,!?;:\"'")
if word:
words.append(word)
return words
def most_common(words):
counts = {}
for word in words:
counts[word] = counts.get(word, 0) + 1
best_word, best_count = "", 0
for word, count in counts.items():
if count > best_count:
best_word, best_count = word, count
return best_word, best_count
def main():
print("=" * 40)
print("TEXT ANALYZER")
print("=" * 40)
text = input("Paste some text: ")
words = clean_words(text)
sentences = text.count(".") + text.count("!") + text.count("?")
word, times = most_common(words)
longest = max(words, key=len) if words else ""
print()
print(f"{'Characters:':<16}{len(text):>6}")
print(f"{'Words:':<16}{len(words):>6}")
print(f"{'Sentences:':<16}{sentences:>6}")
print(f"{'Longest word:':<16}{longest:>6}")
print(f"Most used word: '{word}' ({times} times)")
main()
# Example run:
# Paste some text: Python is fun. Python is powerful! Is it hard? No.
#
# Characters: 50
# Words: 10
# Sentences: 4
# Longest word: powerful
# Most used word: 'is' (3 times)A few things worth noticing:
word.strip(".,!?;:\"'")isstrip()with an argument. Instead of spaces, it removes any of those punctuation marks from the ends of each word, so"fun."becomes"fun"..lower()before counting means"Is"and"is"count as the same word. That's why "is" wins with 3.max(words, key=len)is a handy shortcut: "give me the item with the biggest length." Theif words else ""part just protects us if someone presses Enter without typing anything.
Practice Challenges
Beginner Level
- Shout It: Ask for the user’s name and print it in uppercase, reversed, and with its length.
- Initials: Ask for a full name like
"ajay narayan"and print the initials:A.N.
Intermediate Level
- Palindrome Checker: Ask for a word and say whether it’s the same forwards and backwards (
"Level"should count, so think about capitals). - Vowel Remover: Ask for a sentence and print it with all the vowels removed. Try it with a loop, then try it with
replace().
Advanced Level
- Text Analyzer 2.0: Upgrade the mini project to print the top 3 most used words, and to ignore boring words like “the”, “a”, “is” and “and”. (Hint: a set of stop words, and
sorted()withkey=.)
Before You Go
If strings finally make sense, hit that 👏 clap button.
Run the Text Analyzer on the opening paragraph of your favourite book and tell me in the comments what the most used word was. I’m curious whether it’s always “the”.
Coming up next: Error handling. What happens when someone types “abc” into a program expecting a number? Right now, it crashes. Next time, you’ll learn how to catch errors and keep your program running. Hit Follow so you don’t miss it.
See you in the next post! 🐍
Enjoying this series? Share it with a friend learning Python. Let’s all grow faster, together.
Check out the series so far:
- Python in 2025: Why This Language Still Dominates
- Variables and Data Types
- Python Operators Decoded
- Control Flow Mastery
- Why Write Code Once When It Can Just… Repeat? (Loops)
- Stop Copy-Pasting Your Code (Functions)
- Python Lists: How to Store a Hundred Things in One Variable
- Python Dictionaries: Stop Counting Positions, Start Using Names
- Python Tuples and Sets: The Two Collections Beginners Skip (But Shouldn’t)







