0

I have got a list of strings that I am calling a filter.

filter = ["/This/is/an/example", "/Another/example"] 

Now I want to grab only the strings from another list that start with one of these two (or more, the list will be dynamic). So suppose my list of strings to check is this.

to_check= ["/This/is/an/example/of/what/I/mean", "/Another/example/this/is/", "/This/example", "/Another/freaking/example"] 

When I run it through the filter, I would get a returned list of

["/This/is/an/example/of/what/I/mean", "/Another/example/this/is"] 

Does anyone know if python has a way to do what I am talking about? Grabbing only the strings from a list that start with something from another list?

2
  • 1
    What about /Another/example_you_may_not_have_expected? Does that start with /Another/example or not? Commented Apr 3, 2014 at 17:32
  • Good catch. I will adjust the filter to be "/Another/example/" Commented Apr 3, 2014 at 17:43

2 Answers 2

3

Make filter a tuple and use str.startswith(), it takes either one string or a tuple of strings to test for:

filter = tuple(filter) [s for s in to_check if s.startswith(filter)] 

Demo:

>>> filter = ("/This/is/an/example", "/Another/example") >>> to_check = ["/This/is/an/example/of/what/I/mean", "/Another/example/this/is/", "/This/example", "/Another/freaking/example"] >>> [s for s in to_check if s.startswith(filter)] ['/This/is/an/example/of/what/I/mean', '/Another/example/this/is/'] 

Be careful, when prefix-matching with paths, you generally want to append trailing path separators so that /foo/bar doesn't match /foo/bar_and_more/ paths.

Sign up to request clarification or add additional context in comments.

3 Comments

Just out of curiosity, would this still be a O(n^2) operation?
@warunsl: no, it's a O(nk) operation; n elements in to_check, k elements in filter.
@warunsl: however, the str.startswith() method is implemented in C (check for sufficient length, then a memcmp call), it is hard to make a more efficient algorithm in pure Python that could beat that.
0

Using regular expression.

Try below

import re filter = ["/This/is/an/example", "/Another/example"] to_check= ["/This/is/an/example/of/what/I/mean", "/Another/example/this/is/", "/This/example", "/Another/freaking/example"] for item in filter: for item1 in to_check: if re.match("^"+item,item1): print item1 break 

Output

/This/is/an/example/of/what/I/mean /Another/example/this/is/ 

1 Comment

Regular expressions for a string-prefix match are overkill, especially when str.startswith() accepts a tuple. You cannot hope to beat a loop over k elements implemented in C with a loop over k elements in Python, especially one that adds string concatenation and a function call.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.