Python Strings: Concatenation, f-strings, and Indexing
Python 3.14 Β·
β verified by execution on 2026-07-19
Text values are strings (str), and youβll shape them constantly β greetings, labels,
messages. Start by joining strings together with +, which for text means βstick these
end to endβ:
python
greeting = "Hello" + " " + "World"print(greeting)
Output
Hello World
Your output
That works with variables too:
python
first = "Ada"last = "Lovelace"print(first + " " + last)
Output
Ada Lovelace
Your output
The easy way: f-strings
Joining with + gets clumsy fast β and it breaks the moment you try to mix in a number
(you saw that TypeError earlier). The modern, readable way is an f-string: put f
before the quotes, then drop any variable inside { }:
python
name = "Ada"age = 36print(f"{name} is {age} years old")
Output
Ada is 36 years old
Your output
Notice age is a number, and the f-string inserted it with no fuss β no converting
required. Thatβs why f-strings are the tool youβll reach for again and again.
Measuring length with len()
len() tells you how many characters a string has:
python
print(len("hello"))
Output
5
Your output
And you can combine tools β an f-string with len() inside:
python
word = "Python"print(f"{word} has {len(word)} letters")
Output
Python has 6 letters
Your output
Reaching a single character: indexing
Every character has a position, called its index. The catch that trips up every
beginner: indexing starts at 0, not 1. So the first character is at index 0:
python
word = "Python"print(word[0])
Output
P
Your output
A negative index counts back from the end, so -1 is the last character:
python
word = "Python"print(word[-1])
Output
n
Your output
The mixing error, and the fix
Trying to join text and a number with + fails β Python wonβt guess what you mean:
python
print("Score: " + 100)
This example raises an error (on purpose)
TypeError
Your output
The clean fix is an f-string, which handles the number for you:
python
score = 100print(f"Score: {score}")
Output
Score: 100
Your output
Edge cases worth remembering
Indexing past the end (like "abc"[5]) raises IndexError. For a 3-character string the
valid indexes are 0, 1, 2 (and -1, -2, -3).
Spaces are real characters: len("a b") is 3, and a single space " " has length 1.
Check yourself
What happens when you run print("Score: " + 100)?
Reveal answer
Python raises a TypeError β you can't add text and a number β "Score: " is text and 100 is a number, so + raises TypeError. Use an f-string, f"Score: {100}", or convert with str(100).
In the string "Python", what is at index 0?
Reveal answer
'P' β indexing starts at 0 β Python indexes from 0, so "Python"[0] is 'P', [1] is 'y', and so on.
Which line correctly prints: Ada is 36 years old (with name = "Ada", age = 36)?
Reveal answer
print(f"{name} is {age} years old") β The f-string inserts both values automatically. The second line fails (can't + a number to text); the third has no f, so the braces stay as literal text.
What is len("a b") (note the space)?
Reveal answer
3 β the space is a character too β len() counts every character, and a space is a real character. "a b" is 'a', ' ', 'b' β length 3.
Challenges
Challenge 1 +10 XP
Create a variable city set to "Paris", then use an f-string to print exactly: I love Paris
python
Test 1 β expects "I love Paris"
Need a hint? (β25% XP)
Start the string with f and put {city} where the name should go.
Show solution (0 XP)
city = "Paris"print(f"I love {city}")
Challenge 2 +15 XP
Given word = "Python", print its length on the first line and its last character on the second line.
python
Test 1 β expects "6\nn"
Need a hint? (β25% XP)
len(word) gives the length; word[-1] gives the last character.
Show solution (0 XP)
word = "Python"print(len(word))print(word[-1])
Go deeper
Stacks and Queues, Shown Doing the Jobs They Exist For β Knowing that a stack is last-in-first-out explains nothing about why anyone wanted one. Here a stack matches brackets and catches the error a counter would miss, and a queue runs a ring buffer whose values never move at all.
More Buckets Will Not Save a Bad Hash Function β Hash tables are called O(1) so often that the condition gets dropped. Change the hash function here, drag the table from 4 buckets to 16, and watch the longest chain refuse to move - because memory cannot fix a hash that ignores its input.
In a Trie, Lookup Cost Depends on the Word, Not on How Many Words β A trie stores words letter by letter, sharing every common prefix. Walk one here by clicking letters, and watch the reachable set shrink - that walk is exactly what an autocomplete box does while you type.
99% Accurate, and Mostly Wrong: Why Rare Things Break Good Detectors β A test that gets 99% of its calls right can still be wrong about 92 of every 100 people it flags. Two dials here - how good the test is, and who you point it at - and only one of them can fix that. Find out which before the page tells you.
What Is a Token? Train a Tokenizer and Watch One Form β Language models read tokens, not letters or words. Train a real byte-pair encoding tokenizer on your own text, watch the vocabulary build itself merge by merge, and see why models struggle to spell.
Why ChatGPT Forgets: It Never Remembered β A chat model is stateless. Every turn, the app re-sends the entire conversation β which is why long chats start forgetting the beginning, and why they cost far more than the number of words you typed.
How Many R's in Strawberry? Why That Question Is Unfair β A model that writes working code will confidently miscount the letters in a word. It is not a reasoning failure β the letters were destroyed before the model saw anything. Train a tokenizer and watch it happen.