Single Line For Loop Over Iterator With An "if" Filter?
Solution 1:
No, there is no shorter way. Usually, you will even break it into two lines :
important_airports = (airport forairportin airports if airport.is_important)
forairportin important_airports:
# do stuff
This is more flexible, easier to read and still don't consume much memory.
Solution 2:
Solution 3:
Mabe this, but it's more or less the same verbose...
import itertools
for airport in itertools.ifilter(lambda x: x.is_important, airports):
...
Solution 4:
This is a design philosophy of python. If it takes you too many words to put it on one line, it should be broken into a few lines to help the person who comes after you. List and generator expressions are more for transforming iterables in-place -- making more readable forms of map
and filter
.
Solution 5:
Here's an alternative to some of the other filter versions:
from operator import attrgetter as attr
for airport infilter(attr('is_important'), airports):
...
This has the advantages of being pretty concise and also letting you use dot notation attr('first_class.is_full').
You could also put something like that (or a version using a list comprehension) into a utility function like filter_by_attr. Then you could do:
for airport in filter_by_attr(airports, 'is_important'):
...
I still think e-satis is right to put it in a new variable no matter the method you use, though. It is just clearer that way, especially if the use doesn't exactly match the name of the attribute in question (or the the criteria is more complex).
My only note on that would be that if you find yourself using this in several places, perhaps you should make airports a special collection with 'important_airports' being a @property which returns the filtered collection. Or some sort other abstraction to hide away the filtering (like a service call).
Post a Comment for "Single Line For Loop Over Iterator With An "if" Filter?"