str.startswith()

Does the string begin with this prefix? Clearer and safer than slicing.

String methodPython 2.0+Live demo
Common call
url.startswith("https://")
Returns
bool
Replaces
accepts a tuple: s.startswith(("http://", "https://"))
Watch out
case-sensitive; every string startswith ""
str.startswith(prefixprefixThe prefix to test — or a tuple of prefixes, any of which may match.type: str | tuple[str] · required, startstartTest as if the string began at this index.type: int · default: 0=0, endendTest 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

NameTypeRequiredDescription
prefixstr | tuple[str]yesThe prefix to test — or a tuple of prefixes, any of which may match.
startintno (0)Test as if the string began at this index.
endintno (len(s))Test within the slice ending here (exclusive).

Return value

boolTrue 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
True
2. No match
"hello".startswith("lo")
Returns
False
3. Tuple of prefixes
"https://x".startswith(("http://", "https://"))
Returns
True
4. Empty prefix
"abc".startswith("")
Returns
True

Pitfalls

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.