str.startswith with a list of strings to test for

Question:

I’m trying to avoid using so many comparisons and simply use a list, but not sure how to use it with str.startswith:

if link.lower().startswith("js/") or link.lower().startswith("catalog/") or link.lower().startswith("script/") or link.lower().startswith("scripts/") or link.lower().startswith("katalog/"):
    # then "do something"

What I would like it to be is:

if link.lower().startswith() in ["js","catalog","script","scripts","katalog"]:
    # then "do something"

Is there a way to do this?

Asked By: Eternity

||

Answers:

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
>>>
Answered By: user2555451

You can also use any(), map() like so:

if any(map(l.startswith, x)):
    pass # Do something

Or alternatively, using a generator expression:

if any(l.startswith(s) for s in x)
    pass # Do something
Answered By: user764357

You can also use next() to iterate over the list of patterns.

prefixes = ["xyz", "abc"]
my_string = "abcde"
next((True for s in prefixes if my_string.startswith(s)), False)   # True

One way where next could be useful is that it can return the prefix itself. Try:

next((s for s in prefixes if my_string.startswith(s)), None)       # 'abc'
Answered By: cottontail
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.