Regular expression are costly... In your case why not rely on something like:
found = [
elem
for elem in list_elem
for substring in substrings
if substring.lower() in elem.lower()
]
If you really want to use regular expression I advise you to compile your regex beforehand:
regexes = [
re.compile(r"\b" + substring + r"\b", re.IGNORECASE)
for substring in substrings
]
found = [
elem
for elem in list_elem
for regex in regexes
if regex.search(elem)
]
This should speed up a little bit your execution, but not sure that it is enough to handle a lot of elements.
Finally, if you want to work with sets like in your second code snippet, you can split your sentences and check substring membership.
Here is a code snippet that compare three solutions:
import re
import timeit
def main():
sentences = [
"Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
"Morbi congue lacus vitae dolor tempus, eu auctor elit interdum.",
"Donec eget est sit amet eros pharetra fermentum.",
"Proin volutpat dui eget lacinia lobortis.",
"Pellentesque a ante eu ligula dictum lobortis.",
"Phasellus et velit mattis, finibus velit ut, luctus purus.",
"Integer et risus maximus, varius eros vel, venenatis libero.",
"Proin blandit dui vel ante blandit, et aliquet orci placerat.",
"Suspendisse eu lacus non nunc accumsan congue non id velit.",
"Pellentesque condimentum dui ultricies justo dapibus imperdiet eget eget tortor.",
"Suspendisse faucibus erat a dolor fringilla suscipit.",
"Duis quis tortor convallis purus porttitor elementum.",
"Proin rutrum lacus sed elit convallis porttitor.",
"Nunc sit amet felis ullamcorper, pulvinar augue sed, ullamcorper leo.",
"Ut a erat eu lectus semper pulvinar.",
"Praesent congue velit at nulla finibus hendrerit.",
"Nullam ac erat convallis, suscipit purus quis, dictum eros.",
"Proin condimentum orci nec suscipit imperdiet.",
"Aliquam mattis mauris et turpis sodales tincidunt.",
"Vestibulum vel ante bibendum, interdum ipsum efficitur, porta massa.",
"Duis finibus nisl et urna pharetra, non dignissim ante tempus.",
"Morbi nec lorem eu odio interdum feugiat id sed ligula.",
"Donec nec lorem vitae est consequat dictum.",
"Quisque vehicula quam eu pretium viverra.",
"Etiam luctus metus faucibus, vulputate augue et, luctus enim.",
"Nullam quis elit vitae enim bibendum viverra.",
"Donec consectetur nulla sit amet nulla blandit, sed auctor mi porttitor.",
"Suspendisse vel urna vitae massa mollis dignissim quis eu nulla.",
"Vestibulum id risus fringilla nisl consectetur fringilla.",
"Etiam ut risus ultrices, consequat sapien eu, rhoncus justo.",
"Sed feugiat orci pulvinar, imperdiet massa sit amet, semper dui.",
"Donec nec metus quis nulla sagittis ullamcorper vitae eu ante.",
"Cras vel urna fermentum, tempus magna ut, aliquet dolor.",
"Fusce non urna molestie massa sagittis accumsan et eget lorem.",
"Curabitur ac nisl at mauris pellentesque tincidunt nec sed magna.",
]
substrings = [
"a", "eu", "non", "ac", "at", "et"
]
print("if_in:")
print(if_in(sentences, substrings))
print(timeit.timeit(lambda : if_in(sentences, substrings), number=100))
print("re_compile:")
print(re_compile(sentences, substrings))
print(timeit.timeit(lambda : re_compile(sentences, substrings), number=100))
print("in_set:")
print(in_set(sentences, substrings))
print(timeit.timeit(lambda : in_set(sentences, substrings), number=100))
def if_in(sentences, substrings):
return [
s
for s in sentences
for substring in substrings
if substring.lower() in s.lower()
]
def re_compile(sentences, substrings):
regexes = [
re.compile(r"\b" + substring + r"\b", re.IGNORECASE)
for substring in substrings
]
return [
s
for s in sentences
for regex in regexes
if regex.search(s)
]
def in_set(sentences, substrings):
# Split your sentences on word boundaries (see https://stackoverflow.com/questions/37237594/how-can-i-split-at-word-boundaries-with-regexes)
splitter = re.compile(r'\w+|\W+')
sentence_sets = [set(splitter.findall(s)) for s in sentences]
return [
s
for s, s_set in zip(sentences, sentence_sets)
for sub in substrings
if sub in s_set
]
if __name__ == '__main__':
main()
if_in:
['Lorem ipsum dolor sit amet, consectetur adipiscing elit.', 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.', 'Morbi congue lacus vitae dolor tempus, eu auctor elit interdum.', 'Morbi congue lacus vitae dolor tempus, eu auctor elit interdum.', 'Morbi congue lacus vitae dolor tempus, eu auctor elit interdum.', 'Donec eget est sit amet eros pharetra fermentum.', 'Donec eget est sit amet eros pharetra fermentum.', 'Proin volutpat dui eget lacinia lobortis.', 'Proin volutpat dui eget lacinia lobortis.', 'Proin volutpat dui eget lacinia lobortis.', 'Proin volutpat dui eget lacinia lobortis.', 'Pellentesque a ante eu ligula dictum lobortis.', 'Pellentesque a ante eu ligula dictum lobortis.', 'Phasellus et velit mattis, finibus velit ut, luctus purus.', 'Phasellus et velit mattis, finibus velit ut, luctus purus.', 'Phasellus et velit mattis, finibus velit ut, luctus purus.', 'Integer et risus maximus, varius eros vel, venenatis libero.', 'Integer et risus maximus, varius eros vel, venenatis libero.', 'Integer et risus maximus, varius eros vel, venenatis libero.', 'Proin blandit dui vel ante blandit, et aliquet orci placerat.', 'Proin blandit dui vel ante blandit, et aliquet orci placerat.', 'Proin blandit dui vel ante blandit, et aliquet orci placerat.', 'Proin blandit dui vel ante blandit, et aliquet orci placerat.', 'Suspendisse eu lacus non nunc accumsan congue non id velit.', 'Suspendisse eu lacus non nunc accumsan congue non id velit.', 'Suspendisse eu lacus non nunc accumsan congue non id velit.', 'Suspendisse eu lacus non nunc accumsan congue non id velit.', 'Pellentesque condimentum dui ultricies justo dapibus imperdiet eget eget tortor.', 'Pellentesque condimentum dui ultricies justo dapibus imperdiet eget eget tortor.', 'Suspendisse faucibus erat a dolor fringilla suscipit.', 'Suspendisse faucibus erat a dolor fringilla suscipit.', 'Duis quis tortor convallis purus porttitor elementum.', 'Proin rutrum lacus sed elit convallis porttitor.', 'Proin rutrum lacus sed elit convallis porttitor.', 'Nunc sit amet felis ullamcorper, pulvinar augue sed, ullamcorper leo.', 'Nunc sit amet felis ullamcorper, pulvinar augue sed, ullamcorper leo.', 'Ut a erat eu lectus semper pulvinar.', 'Ut a erat eu lectus semper pulvinar.', 'Ut a erat eu lectus semper pulvinar.', 'Praesent congue velit at nulla finibus hendrerit.', 'Praesent congue velit at nulla finibus hendrerit.', 'Nullam ac erat convallis, suscipit purus quis, dictum eros.', 'Nullam ac erat convallis, suscipit purus quis, dictum eros.', 'Nullam ac erat convallis, suscipit purus quis, dictum eros.', 'Proin condimentum orci nec suscipit imperdiet.', 'Aliquam mattis mauris et turpis sodales tincidunt.', 'Aliquam mattis mauris et turpis sodales tincidunt.', 'Aliquam mattis mauris et turpis sodales tincidunt.', 'Vestibulum vel ante bibendum, interdum ipsum efficitur, porta massa.', 'Duis finibus nisl et urna pharetra, non dignissim ante tempus.', 'Duis finibus nisl et urna pharetra, non dignissim ante tempus.', 'Duis finibus nisl et urna pharetra, non dignissim ante tempus.', 'Morbi nec lorem eu odio interdum feugiat id sed ligula.', 'Morbi nec lorem eu odio interdum feugiat id sed ligula.', 'Morbi nec lorem eu odio interdum feugiat id sed ligula.', 'Donec nec lorem vitae est consequat dictum.', 'Donec nec lorem vitae est consequat dictum.', 'Quisque vehicula quam eu pretium viverra.', 'Quisque vehicula quam eu pretium viverra.', 'Quisque vehicula quam eu pretium viverra.', 'Etiam luctus metus faucibus, vulputate augue et, luctus enim.', 'Etiam luctus metus faucibus, vulputate augue et, luctus enim.', 'Etiam luctus metus faucibus, vulputate augue et, luctus enim.', 'Nullam quis elit vitae enim bibendum viverra.', 'Donec consectetur nulla sit amet nulla blandit, sed auctor mi porttitor.', 'Donec consectetur nulla sit amet nulla blandit, sed auctor mi porttitor.', 'Suspendisse vel urna vitae massa mollis dignissim quis eu nulla.', 'Suspendisse vel urna vitae massa mollis dignissim quis eu nulla.', 'Vestibulum id risus fringilla nisl consectetur fringilla.', 'Vestibulum id risus fringilla nisl consectetur fringilla.', 'Etiam ut risus ultrices, consequat sapien eu, rhoncus justo.', 'Etiam ut risus ultrices, consequat sapien eu, rhoncus justo.', 'Etiam ut risus ultrices, consequat sapien eu, rhoncus justo.', 'Etiam ut risus ultrices, consequat sapien eu, rhoncus justo.', 'Sed feugiat orci pulvinar, imperdiet massa sit amet, semper dui.', 'Sed feugiat orci pulvinar, imperdiet massa sit amet, semper dui.', 'Sed feugiat orci pulvinar, imperdiet massa sit amet, semper dui.', 'Sed feugiat orci pulvinar, imperdiet massa sit amet, semper dui.', 'Donec nec metus quis nulla sagittis ullamcorper vitae eu ante.', 'Donec nec metus quis nulla sagittis ullamcorper vitae eu ante.', 'Donec nec metus quis nulla sagittis ullamcorper vitae eu ante.', 'Cras vel urna fermentum, tempus magna ut, aliquet dolor.', 'Cras vel urna fermentum, tempus magna ut, aliquet dolor.', 'Fusce non urna molestie massa sagittis accumsan et eget lorem.', 'Fusce non urna molestie massa sagittis accumsan et eget lorem.', 'Fusce non urna molestie massa sagittis accumsan et eget lorem.', 'Fusce non urna molestie massa sagittis accumsan et eget lorem.', 'Curabitur ac nisl at mauris pellentesque tincidunt nec sed magna.', 'Curabitur ac nisl at mauris pellentesque tincidunt nec sed magna.', 'Curabitur ac nisl at mauris pellentesque tincidunt nec sed magna.']
0.029533967001043493
re_compile:
['Morbi congue lacus vitae dolor tempus, eu auctor elit interdum.', 'Pellentesque a ante eu ligula dictum lobortis.', 'Pellentesque a ante eu ligula dictum lobortis.', 'Phasellus et velit mattis, finibus velit ut, luctus purus.', 'Integer et risus maximus, varius eros vel, venenatis libero.', 'Proin blandit dui vel ante blandit, et aliquet orci placerat.', 'Suspendisse eu lacus non nunc accumsan congue non id velit.', 'Suspendisse eu lacus non nunc accumsan congue non id velit.', 'Suspendisse faucibus erat a dolor fringilla suscipit.', 'Ut a erat eu lectus semper pulvinar.', 'Ut a erat eu lectus semper pulvinar.', 'Praesent congue velit at nulla finibus hendrerit.', 'Nullam ac erat convallis, suscipit purus quis, dictum eros.', 'Aliquam mattis mauris et turpis sodales tincidunt.', 'Duis finibus nisl et urna pharetra, non dignissim ante tempus.', 'Duis finibus nisl et urna pharetra, non dignissim ante tempus.', 'Morbi nec lorem eu odio interdum feugiat id sed ligula.', 'Quisque vehicula quam eu pretium viverra.', 'Etiam luctus metus faucibus, vulputate augue et, luctus enim.', 'Suspendisse vel urna vitae massa mollis dignissim quis eu nulla.', 'Etiam ut risus ultrices, consequat sapien eu, rhoncus justo.', 'Donec nec metus quis nulla sagittis ullamcorper vitae eu ante.', 'Fusce non urna molestie massa sagittis accumsan et eget lorem.', 'Fusce non urna molestie massa sagittis accumsan et eget lorem.', 'Curabitur ac nisl at mauris pellentesque tincidunt nec sed magna.', 'Curabitur ac nisl at mauris pellentesque tincidunt nec sed magna.']
0.13305247199969017
in_set:
['Morbi congue lacus vitae dolor tempus, eu auctor elit interdum.', 'Pellentesque a ante eu ligula dictum lobortis.', 'Pellentesque a ante eu ligula dictum lobortis.', 'Phasellus et velit mattis, finibus velit ut, luctus purus.', 'Integer et risus maximus, varius eros vel, venenatis libero.', 'Proin blandit dui vel ante blandit, et aliquet orci placerat.', 'Suspendisse eu lacus non nunc accumsan congue non id velit.', 'Suspendisse eu lacus non nunc accumsan congue non id velit.', 'Suspendisse faucibus erat a dolor fringilla suscipit.', 'Ut a erat eu lectus semper pulvinar.', 'Ut a erat eu lectus semper pulvinar.', 'Praesent congue velit at nulla finibus hendrerit.', 'Nullam ac erat convallis, suscipit purus quis, dictum eros.', 'Aliquam mattis mauris et turpis sodales tincidunt.', 'Duis finibus nisl et urna pharetra, non dignissim ante tempus.', 'Duis finibus nisl et urna pharetra, non dignissim ante tempus.', 'Morbi nec lorem eu odio interdum feugiat id sed ligula.', 'Quisque vehicula quam eu pretium viverra.', 'Etiam luctus metus faucibus, vulputate augue et, luctus enim.', 'Suspendisse vel urna vitae massa mollis dignissim quis eu nulla.', 'Etiam ut risus ultrices, consequat sapien eu, rhoncus justo.', 'Donec nec metus quis nulla sagittis ullamcorper vitae eu ante.', 'Fusce non urna molestie massa sagittis accumsan et eget lorem.', 'Fusce non urna molestie massa sagittis accumsan et eget lorem.', 'Curabitur ac nisl at mauris pellentesque tincidunt nec sed magna.', 'Curabitur ac nisl at mauris pellentesque tincidunt nec sed magna.']
0.11130324300029315
As you can see, the first solution is very fast but returns too many result because it misses the "word boundary" constraint on substring.
Other solutions are quiet equivalent (multiple runs give sometimes one faster than the other and sometimes the inverse).
re_compile
should be faster if you have few substrings to test, else in_set
should be faster if you have few sentences.
I don't know about the Trie data structure proposed by karnesJ.R,
but it can be a good idea to re-think your algorithm if you really have a lot of elemets.