Q1When word = "python", what is word[-2]?
How to Use Python Strings (str)
Learn the Python str type by running every example in your browser, from quoting styles to the methods you'll reach for every day.
Creating a string
A string (str) is a type that represents a "sequence of characters." In Python, any value wrapped in quotes is a str.
There are three ways to wrap a string, and you pick the one that fits your situation.
All three produce the same str type.
The choice comes down to "which symbols appear inside the text" and "whether you need line breaks."
When you want to include a line break, you either use the \n escape sequence or wrap the text in triple quotes.
# Single/double quotes are for one-line strings
fruit1 = 'apple'
fruit2 = "banana"
# When the text contains ', wrapping in " is easier
message = "it's a pen"
# To include line breaks -> use \n or triple quotes
text_a = "apple\nbanana\ngrape"
text_b = """apple
banana
grape"""
print(fruit1, fruit2) # apple banana
print(message) # it's a pen
print(text_a) # displayed on 3 lines
print(text_b) # same result as text_a
Pulling out characters by position (indexing and slicing)
You can also pull characters out of a string by position (an index).
The important thing is that indexes start at 0. The first character isn't "position 1" — it's position 0.
Get one character — [i]
Write string[position] to pull out the single character at that position.
Use a negative number to count from the end. -1 is the very last character.
fruit = "lemon" # l e m o n
print(fruit[0]) # l (first)
print(fruit[2]) # m (3rd)
print(fruit[-1]) # n (last)
print(fruit[-2]) # o (2nd from the end)
# Going out of range raises an error
# print(fruit[10]) # IndexError
Extract a range — slicing with [a:b]
Write string[start:end] to pull out everything from the start position up to, but not including, the end position. This is called a slice.
The key point is the half-open range — "up to one before the end." [0:3] gives you positions 0, 1, and 2 (three characters), and does not include 3.
[a:b] includes a and excludes b.
Omit a to start from the beginning; omit b to go to the end.
Negative numbers work too — [-3:] is the last 3 characters.
msg = "0123456789"
print(msg[0:3]) # '012' (3 is not included)
print(msg[:4]) # '0123' (from the start)
print(msg[4:]) # '456789'(to the end)
print(msg[-3:]) # '789' (last 3 characters)
print(msg[:-3]) # '0123456'(everything except the last 3)
You can also add a third number — [start:end:step] — to pick every other (or every few) characters. [::2] grabs every second character.
That said, cramming the step and the range into one line gets hard to read, so for longer slices it's better to split them across two lines.
msg = "0123456789"
# [::step] skips through the string
print(msg[::2]) # '02468' (every other)
print(msg[::3]) # '0369' (every third)
# Splitting the step onto its own line reads better
head = msg[:6] # '012345'
skip = head[::2] # '024' (every other)
print(skip)
Methods that transform a string
Strings come with built-in features that produce a new string based on the original, and those are called methods.
You call one by writing variable.method_name(). The key point is that the original string is never changed — a new string is returned.
Match case — upper / lower
upper() converts to all uppercase, and lower() converts to all lowercase.
The most common use is comparing strings while ignoring case. User-entered names and email addresses often arrive with inconsistent casing, so you normalize both sides to the same case before comparing.
name = "Alice"
print(name.lower()) # alice
print(name.upper()) # ALICE
print(name) # Alice (original is unchanged)
# Check if the two names match, ignoring case
input_a = "ALICE"
input_b = "alice"
print(input_a.lower() == input_b.lower()) # True
Replace content and trim edges — replace / strip
replace("before", "after") returns a new string where every "before" has been swapped for "after".
strip() is the method that removes whitespace from both ends. It's perfect for cleaning up stray spaces that users accidentally paste into a form.
greeting = "Hello World"
print(greeting.replace("World", "Python")) # Hello Python
print(greeting) # Hello World (original is unchanged)
# Trim stray whitespace (only the edges — spaces inside stay)
raw = " alice@example.com "
print(raw.strip()) # 'alice@example.com'
print(len(raw)) # 21 (including spaces)
print(len(raw.strip())) # 17 (spaces are gone)
Methods that inspect a string
Next up are methods that don't change the value — they just tell you something about the string.
They count occurrences of a character, check the beginning or end, find positions, and inspect what kind of characters are inside.
Check what's inside — count / startswith / endswith / find
- count("text") — returns how many times
textappears, as a number - startswith("text") — returns whether the string starts with
text(True / False) - endswith("text") — returns whether the string ends with
text(True / False) - find("text") — returns the position of the first match. If nothing is found, it returns
-1
msg = "abcCBAabc"
print(msg.count("a")) # 3 (there are 3 a's)
print(msg.count("abc")) # 1 ('abc' appears as a run only once)
print(msg.startswith("abc")) # True
print(msg.endswith("abc")) # True
print(msg.find("CBA")) # 3 (starts at position 3)
print(msg.find("xyz")) # -1 (not found, so -1)
endswith is the go-to for file extensions
Something like filename.endswith(".png") gives you a quick way to check whether a file is an image. It is case-sensitive, so if the casing could be mixed, go with filename.lower().endswith(".png") to stay safe.
Inspect character types — isdigit / isalpha / islower / isupper
The is...() family of methods returns True / False based on whether the entire string satisfies the condition. Note that a single space or symbol mixed in is enough to make them return False.
| Method | Returns True when |
|---|---|
| isdigit() | every character is a digit (0–9) |
| isalpha() | every character is a letter, including CJK characters (False if any whitespace, digit, or symbol is mixed in) |
| isupper() | every letter is uppercase |
| islower() | every letter is lowercase |
print("123".isdigit()) # True
print("12a".isdigit()) # False (an 'a' is mixed in)
print("Tokyo".isalpha()) # True
print("Tokyo 2024".isalpha())# False (contains a space and digits)
print("HELLO".isupper()) # True
print("Hello".islower()) # False
Don't use isdigit to check "can this be a number"
isdigit() only returns True for strings that look like non-negative integers. "-12" and "3.14" both return False. When you need to handle strings with minus signs or decimal points as numbers, skip isdigit() and instead pass the string to int() / float() and use exception handling to check if it worked.
In this article you learned the three kinds of quotes, how to extract characters with indexing and slicing, and a set of transformation and inspection methods.
Strings are one of the most common types you'll use in a program. The methods shown here are directly reusable when you start handling user input in later articles, so spend a bit of time running the examples to build a feel for them.
Knowledge Check
Answer each question one by one.
Q2When s = "abcdefg", what is s[1:4]?
Q3What is the result of " Hello World ".strip().lower()?