regular expressions search list, but return list of same size

Viewed 106

Similar to this question: Regular Expressions: Search in list

But I'd like to return a list of the same size of the searched list, with None or '' where there are no matches:

import re

mylist = ["dog", "cat", "wildcat", "thundercat", "cow", "hooo"]
r = re.compile(".*cat")
list(filter(r.match, mylist)) 

# looking for  ["", "cat", "wildcat", "thundercat", "", ""]

I tried removing filter but that returns the whole list

Also tried

[r.match(x) for x in mylist]

but this returns:

[None,
 <regex.Match object; span=(0, 3), match='cat'>,
 <regex.Match object; span=(0, 7), match='wildcat'>,
 <regex.Match object; span=(0, 10), match='thundercat'>,
 None,
 None]

And I don't know how to extract the strings

.group(0) throws an error for None

Either method works, preference to what is faster/more efficient as the list will be a long one

4 Answers

A non-regex solution should also be fine.

If you want the string to end with cat, you can use str.endswith:

>>> [x if x.endswith('cat') else '' for x in mylist]
['', 'cat', 'wildcat', 'thundercat', '', '']

If cat can appear anywhere in the string, you can use in operator:

>>> [x if 'cat' in x else '' for x in mylist]
['', 'cat', 'wildcat', 'thundercat', '', '']

Here's one way:

[m.group(0) if m else "" for m in map(r.match, mylist)]

Produces:

['', 'cat', 'wildcat', 'thundercat', '', '']

You may use an alternation in regex to get empty match for a non-match:

import re

mylist = ["dog", "cat", "wildcat", "thundercat", "cow", "hooo"]
rx = re.compile(r'.*cat|^')

print( [rx.findall(i)[0] for i in mylist] )

Regex .*cat|^ matches a string that has cat or just the line start to make sure empty match when cat is not matched.

RegEx Demo

Output:

['', 'cat', 'wildcat', 'thundercat', '', '']

Just add and x to your almost working attempt:

[r.match(x) and x for x in mylist]

Result:

[None, 'cat', 'wildcat', 'thundercat', None, None]

Or

[m(x) and x for x in mylist]

after m = r.match.

Related