1
for module in host.modules:
    for removal in removal_re:
        compile_re = re.compile(removal)
        if compile_re.match(module.name):
            removed_modules.append(module)
            continue

How am I able to do the above using list comprehension? I've tried researching a lot on list comp but can't seem to get my head around it for some reason. Any ideas/suggestions?

1
  • 3
    Just a comment: List comprehensions aren't per sei better than for loops. From the Zen of Python: Simple is better than complex. Commented Nov 5, 2018 at 8:57

3 Answers 3

4

You can use any to add the module to the list if any of the regex matches without evaluating them all. Also, re.compile does not really help if you use the regex just once:

removed_modules = [module for module in host.modules
                   if any(re.match(removal, module.name) for removal in removal_re)]

(Note: I assume you meant break instead of continue, which does nothing in your code and would result in module being added multiple times to the list if it matches more than one regex.)

Also, despite what other answers say (some of which seem to misunderstand what the loop is doing), I think in this case, the list comprehension is more readable and clearer than the loop.

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

Comments

0

Generally, you can somehow translate loops into list comprehensions with the following scheme:

new_list = []

for element in old_list:
    if condition:
        new_element = func(element)
        new_list.append(new_element)

Does the same trick as:

new_list = [func(element) for element in old_list if condition]

The func can be anything that alters the original list element. Maybe this helps you to get your head around list comprehensions.

Comments

0

your code is much more readable than a list comprehension, but let's walk through it

the typical syntax is something like this

 [expression(item) for item in list if condition]

this will return a list, if you don't assign the list comp to a variable then it will just perform the expression len(list) times once for ever item in the list. the if statement is optional. knowing this let's change your code up a little bit, you can see the hard part is getting the inner loop done, so let's do that first

for module in host.modules:
    removed_modules = [module for removal in removal_re if re.compile(removal).match(module.name)]

ok so that's already not pep 8 compliant because it's too long but for the sake of argument you can see we made a list of removed modules and we're looping through the modules in host.modules doing this over and over.

this means that what's under this new for loop can become the expression we talked about earlier, and the module can become the item and we end up with this

[[module for removal in removal_re if re.compile(removal).match(module.name)] for module in host.modules]

hey presto a one liner but just remember, just because you can do something doesn't mean that you should!

4 Comments

Agreed that if OP were adding the compiled regex to te final list, the loop would be simpler than a list comp. Problem is, OP is not adding the compiled regex to the final list, much less a list of lists.
while it is true that my cod returns a list of lists, this can be flattened with something like [x for y in z for x in y]. i believe OP was looking for more of an explanation of list comprehensions than a perfect reproduction of their loop
Yes, but even after you flatten the list of lists, you have a list of compiled regexes that matched one or more of the modules. How are you supposed to get the modules they matched from those?
you are correct, i have changed it to fix that issue

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.