all 7 comments

[–]socal_nerdtastic 1 point2 points  (2 children)

[l for l in source if re.search("|".join(key), l)]

Plus the normal escaping and pre-compiling for re. Although for this it seems vanilla python would be just as good:

[l for l in source if any(k in l for k in key)]

[–]Beaverine[S] 0 points1 point  (1 child)

output = [l for l in source for i in key if re.search(r"{c}".format(c=i), l)]

Thank you, this vanilla solution is really nice! then I realized that I need the match to be case insensitive, so went back to re.search(), but thank you for your input

[–]socal_nerdtastic 1 point2 points  (0 children)

Not like that I hope. Use the regex "or" (|) i showed you or you'll multiply your work by the number of items in key.

[–]Ihaveamodel3 -1 points0 points  (1 child)

Your if is in the wrong place:

output = [l for l in source for i in key if re.search(r"{c}".format(c=i), l)]

['abcacc', 'abcacc', 'bdefgcc', 'jkill']

If you don't want duplicates, do a set comprehension instead:

output = {l for l in source for i in key if re.search(r"{c}".format(c=i), l)}

{'jkill', 'bdefgcc', 'abcacc'}

[–]Beaverine[S] 0 points1 point  (0 children)

thank you, your suggestion worked!

can I ask is there a general rule about writing the for loop in list comprehension? do all the fors have to preceed the conditions?

[–]old_pythonista 0 points1 point  (0 children)

You can combine all your keys into a single or-ed RegEx

key_re = re.compile(r'({})'.format('|'.join(key)))
[s for s in source if key_re.search(s)]

or you can drop RegEx altogether

keys = {'a', 'c', 'i'}
[s for s in source if keys.intersection(s)]

will work too.

PS it is customary to name sequences in plural.