str.startswith()
Does the string begin with this prefix? Clearer and safer than slicing.
Common call
url.startswith("https://")
Returns
bool
Replaces
accepts a tuple: s.startswith(("http://", "https://"))
Watch out
case-sensitive; every string startswith ""
str.startswith(prefixprefix — The prefix to test — or a tuple of prefixes, any of which may match.type: str | tuple[str] · required, startstart — Test as if the string began at this index.type: int · default: 0=0, endend — Test within the slice ending here (exclusive).type: int · default: len(s)=len(s))
→ bool
Demo
Live evaluation
Try:
Inputs
stringstrthe source
prefixstrthe prefix
Output
'https://example.com'.startswith('https://')
True
A straightforward boolean: does the string begin with exactly this prefix? Case matters, and the empty prefix matches everything.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| prefix | str | tuple[str] | yes | The prefix to test — or a tuple of prefixes, any of which may match. |
| start | int | no (0) | Test as if the string began at this index. |
| end | int | no (len(s)) | Test within the slice ending here (exclusive). |
Return value
bool — True when the (optionally sliced) string begins with prefix. Also accepts a tuple of prefixes — True if any matches.
Common patterns
Protocol / scheme checks
The tuple form covers alternatives in one call.
if url.startswith(("http://", "https://")): fetch(url)
Skip comment lines
A classic file-parsing filter.
lines = [ln for ln in f if not ln.startswith("#")]
Dispatch on a command prefix
Cheap routing before real parsing.
if cmd.startswith("git "): handle_git(cmd)
Examples
1. Basic prefix test
"hello".startswith("he")
Returns
True2. No match
"hello".startswith("lo")
Returns
False3. Tuple of prefixes
"https://x".startswith(("http://", "https://"))
Returns
True4. Empty prefix
"abc".startswith("")
Returns
TruePitfalls
1. Case-sensitive
Normalize first for case-insensitive prefix checks.
Misses
"Hello".startswith("hello")
False
Fix
"Hello".lower().startswith("hello")
True
2. A list of prefixes raises
The multi-prefix form requires a tuple specifically.
Raises
s.startswith(["a", "b"])
TypeError: startswith first arg must be str or a tuple of str
Fix
s.startswith(("a", "b"))
works — tuple, not list
3. Slicing comparisons are the fragile alternative
s[:8] == "https://" breaks silently if the literal and length drift apart.
Fragile
if s[:7] == "https://": # length is 8!
never True
Fix
if s.startswith("https://"):
no length to keep in sync
When to use
Use it
- Prefix checks of any kind — clearer than slicing
- Several acceptable prefixes → the tuple form
- Filtering lines / paths / identifiers by their start
Reach for something else
- Remove the prefix too → str.removeprefix
- Pattern anchors → re.match
- Suffix instead → str.endswith
Notes
Complexity
O(len(prefix))
Return
bool
CPython impl
Objects/unicodeobject.c :: unicode_startswith
Memory
No allocation
Thread-safe
Yes — str is immutable
FAQ
str.endswith — identical contract at the other end, including the tuple form.
name.endswith((".jpg", ".png"))
History
2.5
Tuple-of-prefixes form added.
2.0
Method available on the unified string type.