str.startswith allows you to supply a tuple of strings to test for:

if link.lower().startswith(("js", "catalog", "script", "katalog")):

From the docs:

str.startswith(prefix[, start[, end]])

Return True if string starts with the prefix, otherwise return False. prefix can also be a tuple of prefixes to look for.

Below is a demonstration:

>>> "abcde".startswith(("xyz", "abc"))
True
>>> prefixes = ["xyz", "abc"]
>>> "abcde".startswith(tuple(prefixes)) # You must use a tuple though
True
>>>
Answer from user2555451 on Stack Overflow
๐ŸŒ
W3Schools
w3schools.com โ€บ python โ€บ ref_string_startswith.asp
Python String startswith() Method
Python Examples Python Compiler ... Q&A Python Training ... The startswith() method returns True if the string starts with the specified value, otherwise False....
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ python โ€บ python-string-startswith
Python - String startswith() - GeeksforGeeks
April 29, 2025 - startswith() method in Python checks whether a given string starts with a specific prefix.
Discussions

python - str.startswith with a list of strings to test for - Stack Overflow
I'm trying to avoid using so many comparisons and simply use a list, but not sure how to use it with str.startswith: More on stackoverflow.com
๐ŸŒ stackoverflow.com
Python: startswith any alpha character - Stack Overflow
How can I use the startswith function to match any alpha character [a-zA-Z]. For example I would like to do this: if line.startswith(ALPHA): Do Something More on stackoverflow.com
๐ŸŒ stackoverflow.com
Strange behavior when using String.startswith() with an empty string and a big start
When using 'test'.startswith(''), it came out as True, I was under the impression that startswith() was doing something like this: string[start:end] == value, but whenever start is equal or greater than the length of the string it results in False. So, I thought that values that would result ... More on discuss.python.org
๐ŸŒ discuss.python.org
3
0
September 29, 2021
python - How to use str.startswith with multiple strings? - Stack Overflow
I've tried using the or function to input multiple words for the same output, but it only takes the first word as the input and not the rest. How do I solve this? Thanks! For instance: message.cont... More on stackoverflow.com
๐ŸŒ stackoverflow.com
๐ŸŒ
Codecademy
codecademy.com โ€บ docs โ€บ python โ€บ strings โ€บ .startswith()
Python | Strings | .startswith() | Codecademy
April 17, 2025 - The .startswith() method in Python checks whether a string begins with a specified value and returns True if it does. Otherwise, it returns False.
๐ŸŒ
Career Karma
careerkarma.com โ€บ blog โ€บ python โ€บ python startswith and endswith: step-by-step guide
Python Startswith and Endswith: Step-By-Step Guide | Career Karma
December 1, 2023 - Because each character has its own index number, we can manipulate strings based on where each letter is located. The startswith() string method checks whether a string starts with a particular substring.
Find elsewhere
๐ŸŒ
YouTube
youtube.com โ€บ watch
How To Use Startswith Method In Python - YouTube
In this video we will learn How To Use Startswith Method In Python. The startswith method in python (startswith()), is a string method that can be used to ch...
Published: December 6, 2022
๐ŸŒ
Learn By Example
learnbyexample.org โ€บ python-string-startswith-method
Python String startswith() Method - Learn By Example
April 20, 2020 - Python ยท Determines whether the string starts with a given substring ยท The startswith() method returns True if the string starts with the specified prefix, otherwise returns False.
๐ŸŒ
Python
docs.python.org โ€บ 3 โ€บ builtins โ€บ stdtypes.html
Built-in Types โ€” Python 3.14.7 documentation
>>> 'Python'.startswith('Py') True >>> 'a tuple of prefixes'.startswith(('at', 'a')) True >>> 'Python is amazing'.startswith('is', 7) True
๐ŸŒ
Programiz
programiz.com โ€บ python-programming โ€บ methods โ€บ string โ€บ startswith
Python String startswith()
Online Python Online JavaScript ... Online Rust Online Scala Online Dart Online R Online Ruby ... The startswith() method returns True if a string starts with the specified prefix(string)....
๐ŸŒ
Python.org
discuss.python.org โ€บ python help
Strange behavior when using String.startswith() with an empty string and a big start - Python Help - Discussions on Python.org
September 29, 2021 - When using 'test'.startswith(''), it came out as True, I was under the impression that startswith() was doing something like this: string[start:end] == value, but whenever start is equal or greater than the length of the string it results in False. So, I thought that values that would result in out of bounds in other languages would all return False, but 'test'.startswith('', 0, 99), 'test'.startswith('', -99, 99) and 'test'.startswith('', -99, -99) return True.
๐ŸŒ
Pandas
pandas.pydata.org โ€บ docs โ€บ reference โ€บ api โ€บ pandas.Series.str.startswith.html
pandas.Series.str.startswith โ€” pandas 3.0.6 documentation
str.startswith ยท Python standard library string method. Series.str.endswith ยท Same as startswith, but tests the end of string. Series.str.contains ยท Tests if string element contains a pattern. Examples ยท >>> s = pd.Series(["bat", "Bear", "cat", np.nan]) >>> s 0 bat 1 Bear 2 cat 3 NaN dtype: str ยท
๐ŸŒ
Tutorialspoint
tutorialspoint.com โ€บ python โ€บ string_startswith.htm
Python String startswith() Method
The Python string method startswith() checks whether string starts with a given substring or not. This method accepts a prefix string that you want to search for and is invoked on a string object.
Top answer
1 of 10
33

I'd agree with the others that startswith is more readable, and you should use that. That said, if performance is a big issue for such a special case, benchmark it:

$ python -m timeit -s 'text="foo"' 'text.startswith("a")'
1000000 loops, best of 3: 0.537 usec per loop

$ python -m timeit -s 'text="foo"' 'text[0]=="a"'
1000000 loops, best of 3: 0.22 usec per loop

So text[0] is amost 2.5 times as fast - but it's a pretty quick operation; you'd save ~0.3 microseconds per compare depending on the system. Unless you're doing millions of comparisons in a time critical situation though, I'd still go with the more readable startswith.

2 of 10
33

text[0] fails if text is an empty string:

IronPython 2.6 Alpha (2.6.0.1) on .NET 4.0.20506.1
Type "help", "copyright", "credits" or "license" for more information.
>>> text = ""
>>> print(text.startswith("a"))
False
>>> print(text[0]=='a')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: index out of range: 0

EDIT: You say you "know" that text is not empty... how confident are you of that, and what would you want to happen if it is empty in reality? If a failure is appropriate (e.g. it means a bug in your code) that would encourage the use of text[0]=='a'.

Other questions:

  • How concerned are you about the performance of this? If this is performance critical, then benchmark it on your particular Python runtime. I wouldn't be entirely surprised to find that (say) one form was faster on IronPython and a different one faster on CPython.

  • Which do you (and your team) find more readable?

๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ python โ€บ python-check-if-string-starts-with-any-element-in-list
Python - Check if string starts with any element in list - GeeksforGeeks
July 12, 2025 - startswith() method in Python can accept a tuple of strings to check if the string starts with any of them.
Top answer
1 of 3
34

There is technically no reason to accept other sequence types, no. The source code roughly does this:

if isinstance(prefix, tuple):
    for substring in prefix:
        if not isinstance(substring, str):
            raise TypeError(...)
        return tailmatch(...)
elif not isinstance(prefix, str):
    raise TypeError(...)
return tailmatch(...)

(where tailmatch(...) does the actual matching work).

So yes, any iterable would do for that for loop. But, all the other string test APIs (as well as isinstance() and issubclass()) that take multiple values also only accept tuples, and this tells you as a user of the API that it is safe to assume that the value won't be mutated. You can't mutate a tuple but the method could in theory mutate the list.

Also note that you usually test for a fixed number of prefixes or suffixes or classes (in the case of isinstance() and issubclass()); the implementation is not suited for a large number of elements. A tuple implies that you have a limited number of elements, while lists can be arbitrarily large.

Next, if any iterable or sequence type would be acceptable, then that would include strings; a single string is also a sequence. Should then a single string argument be treated as separate characters, or as a single prefix?

So in other words, it's a limitation to self-document that the sequence won't be mutated, is consistent with other APIs, it carries an implication of a limited number of items to test against, and removes ambiguity as to how a single string argument should be treated.

Note that this was brought up before on the Python Ideas list; see this thread; Guido van Rossum's main argument there is that you either special case for single strings or for only accepting a tuple. He picked the latter and doesn't see a need to change this.

2 of 3
22

This has already been suggested on Python-ideas a couple of years back see: str.startswith taking any iterator instead of just tuple and GvR had this to say:

The current behavior is intentional, and the ambiguity of strings themselves being iterables is the main reason. Since startswith() is almost always called with a literal or tuple of literals anyway, I see little need to extend the semantics.

In addition to that, there seemed to be no real motivation as to why to do this.

The current approach keeps things simple and fast, unicode_startswith (and endswith) check for a tuple argument and then for a string one. They then call tailmatch in the appropriate direction. This is, arguably, very easy to understand in its current state, even for strangers to C code.

Adding other cases will only lead to more bloated and complex code for little benefit while also requiring similar changes to any other parts of the unicode object.