The str.endswith() method checks whether a string ends with a specified suffix, returning True if it matches and False otherwise. It accepts either a single string or a tuple of multiple suffixes, making it the standard idiom for file extension filtering and URL routing.
Prefix Equivalent: To check whether a string begins with a prefix, use str.startswith().
The endswith() method is called directly on a string instance:
str.endswith(suffix[, start[, end]])
| Parameter | Type | Required? | Description |
|---|---|---|---|
suffix |
str or tuple[str, ...] |
Yes | A string suffix to match, or a tuple of candidate suffixes to check against. |
start |
int |
No (default: 0) |
Optional starting index position from which to begin testing the string. |
end |
int |
No (default: len(string)) |
Optional ending index position where the test segment terminates. |
Return Value: Returns True if the string (or the designated slice) ends with the specified suffix; otherwise False.
In standard use, pass a single target string suffix:
domain = "www.plus2net.com"
print(domain.endswith("com")) # True
print(domain.endswith(".com")) # True
print(domain.endswith("org")) # False
print(domain.endswith("plus2net")) # False
True
True
False
False
One of Python's most convenient features is passing a tuple of candidates to endswith(). If the string ends with any of the elements in the tuple, the method returns True:
image_filename = "avatar_profile.png"
# Define candidate extensions as a tuple
supported_images = (".jpg", ".jpeg", ".png", ".webp")
if image_filename.endswith(supported_images):
print("Valid image file format accepted.")
else:
print("Unsupported file format.")
['.jpg', '.png'] will raise a TypeError: tuple for startswith -- or endswith -- must be tuple, not list.
Like all Python string comparisons, endswith() is strictly case-sensitive. The string "REPORT.PDF" will not match suffix ".pdf":
file = "Annual_Report.PDF"
print(file.endswith(".pdf")) # False! (Case mismatch)
# Idiomatic Solution: Normalize with lower() before matching
print(file.lower().endswith(".pdf")) # True
The optional start and end parameters restrict the test to a slice of the string (equivalent to string[start:end].endswith(suffix)), but without allocating a new substring in memory:
text = "Welcome to plus2net.com"
# Index: 0123456789...
# Check if substring text[0:7] ("Welcome") ends with "come"
print(text.endswith("come", 0, 7)) # True
# Check if substring text[0:6] ("Welcom") ends with "come"
print(text.endswith("come", 0, 6)) # False
# Check if substring text[11:19] ("plus2net") ends with "net"
print(text.endswith("net", 11, 19)) # True
"")Testing for an empty string suffix always returns True, even on an empty string:
print("database".endswith("")) # True
print("".endswith("")) # True
Passing numbers or other types directly raises a TypeError:
try:
"order_number_105".endswith(105)
except TypeError as err:
print("Caught:", err)
# Output: Caught: endswith first arg must be str or a tuple of str, not int
Python provides multiple ways to test string endings. Here is how they compare:
| Approach | Syntax | Pros | Cons |
|---|---|---|---|
str.endswith() |
s.endswith(('.a', '.b')) |
Readable, fast C implementation, accepts tuples directly. | Fixed substring matching only (no patterns). |
| Negative Slicing | s[-4:] == '.pdf' |
Basic syntax without method call. | Crashes or misbehaves if string is shorter than slice length; awkward for multiple extensions. |
Regular Expressions (re) |
re.search(r'\.(pdf|docx)$', s) |
Supports complex patterns and wildcard rules. | Higher compilation overhead and less readable for simple extension checks. |
Let's build a document ingestion classifier that sorts incoming file uploads into allowed documents, images, and rejected files using endswith() with tuples and case normalization, verified with unit assertions:
def categorize_file(filename):
DOC_EXTS = (".pdf", ".docx", ".xlsx", ".csv")
IMG_EXTS = (".jpg", ".jpeg", ".png", ".webp")
lower_name = filename.lower()
if lower_name.endswith(DOC_EXTS):
return "DOCUMENT"
elif lower_name.endswith(IMG_EXTS):
return "IMAGE"
else:
return "UNSUPPORTED"
# Unit Assertions
assert categorize_file("Q3_Financials.XLSX") == "DOCUMENT"
assert categorize_file("contract_signed.pdf") == "DOCUMENT"
assert categorize_file("banner_logo.PNG") == "IMAGE"
assert categorize_file("photo.JPEG") == "IMAGE"
assert categorize_file("malicious_script.exe") == "UNSUPPORTED"
assert categorize_file("README") == "UNSUPPORTED"
print("All file categorization unit assertions passed successfully!")
Author & Instructor at plus2net
I write and maintain practical tutorials on Python, PHP, SQL, JavaScript, HTML, jQuery, and web development at plus2net. The tutorials focus on clear explanations, working examples, and code that readers can test and adapt while learning.