3

Is it possible to basically do the following in Python:

for elem in my_list if elem:
    #Do something with elem...

Note that I want to specifically avoid using map, lambdas, or filter to create a second list that gives the Boolean condition, and I don't want to do the following:

for elem in [item for item in my_list if item]:
    #Do something...

The latter method requires the construction of the Boolean list too. In my code, my_list can be very, very large.

Basically, the simplest way would be to write

for elem in my_list:
    if elem:
        #Do stuff...

but I specifically want this all in one line. If all-in-one-line won't make the code actually any different than this last example I gave, that's fine too and I will go with that.

7
  • Define "do something with elem". Commented Nov 10, 2011 at 4:43
  • That shouldn't be relevant. Just any normal body of a for-loop. We could just use print elem as an example, but it's not relevant. Assume I want to print all of the non-empty strings in my_list using only one single conditional statement and only one pass through my_list without forming a new list that contains only the non-empty strings from my_list. Commented Nov 10, 2011 at 4:44
  • It's relevant for the reason that you can often reasonably refactor the whole thing into a list comprehension. That wouldn't seem to make sense for printing, until you realise that you can do something like print '\n'.join(item for item in my_list if item != ''). Commented Nov 10, 2011 at 4:47
  • if not (elem=='') is equivalent to if elem assuming they're all strings. Commented Nov 10, 2011 at 4:48
  • @agf Thanks, I updated. I was aware, but it's probably good so that others don't all point that out too. Commented Nov 10, 2011 at 4:51

2 Answers 2

11

You can use a generator expression instead of a list comprehension.

for elem in (item for item in my_list if not (item=='')):
    #Do something...
Sign up to request clarification or add additional context in comments.

4 Comments

When the documentation says this is evaluated "lazily" does this mean the generator expression won't go and get the next value of item until the for elem part requests it?
Yes. The next value will only be evaluated when for needs it.
@EMS: For example: a = range(3); g = ((x, y) for x in a for y in b). Initially 'a' has to exist but not 'b'. The iterator for 'b' is evaluated after next(g) triggers the nested loop.
Thank you guys for the concise answers and for further explaining the generators. I think other answers/comments assumed I was not competent or something... I've used list comprehensions a ton, just never had heard of generators to avoid creating the whole returned list.
2

Check out the ifilter() function in itertools.

4 Comments

Specifically ifilter(None, my_list) in this case.
It appears that since ifilter uses yield, it is also a generator expression, so is it correct that it doesn't return the whole list, just the elements as they are requested?
@EMS ifilter doesn't actually use yield, it's implemented in C. But yes, all of itertools works like that; it's the entire point of the module.
The documentation for ifilter says that it does use yield.

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.