I have a procedure which requires me to check each value in a List against every other value in the same List. If I identify something that meets some requirement, I add it to another List to be removed after this procedure is finished.
Pseudo-code:
for value1 in my_list:
for value2 in my_list:
if meets_requirements(value1, value2):
to_be_removed.append(value2)
This looks ugly to me. Naming conventions for the variables are difficult to assign or understand. There's the potential (although very un-likely, in this case) I could accidentally modify the list while iterating it. There may be issues with performance.
Is there a better alternative to performing these double iterations?
If not, are there any ways I can make this more readable and "feel" like quality code?
You don't have to find the removed values first. Just create the list you need in one shot:
my_list = [y for y in my_list
if not any(meets_requirement(x,y) for x in my_list)]
You can use itertools.product
here. Though this is still equivalent to nested loops, but much more readable:
from itertools import product
for value1, value2 in product(my_list, repeat=2):
if meets_requirements(value1, value2):
to_be_removed.append(value2)
I would have used a list comprehension together with product()
from the itertools
module:
from itertools import product
to_be_removed = [v2 for v1, v2 in product(mylist, repeat=2)
if meets_requirement(v1, v2)]
Following @tobias_k's comment, if you don't want multiple instances of the same values in your result, and if the order of the elements doesn't matter, you can use a set comprehension instead:
to_be_removed = {v2 for v1, v2 in product(mylist, repeat=2)
if meets_requirement(v1, v2)}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With