Using while in list comprehension or generator expressions
Asked Answered
S

2

21

I can use if and for in list comprehensions/generator expressions as

list(i for i in range(100) if i*i < 30)

I know this is not the most efficient but bear with me as the condition could be much more complicated and this is just an example. However, this still goes through hundred iterations and only yields a value in the first 6. Is there a way to tell the generator expression where to stop with something like this:

list(i for i in range(100) while i*i < 30)

However, while is not understood in generator expressions. So, my question is, how do I write a generator expression with a stopping condition so it does not continue computation, even if it doesn't yield new values.

Seriatim answered 31/3, 2011 at 20:27 Comment(2)
Just a note: you can generate a list directly by using [i for i in range(100)]Evocation
Curiously, there was PEP3142 open at the time this question was asked. The use case given is almost exactly this one. Guido nuked it in May, 2013Sudan
S
14

The various functions in itertools (takewhile() comes to mind) can help.

Samoyedic answered 31/3, 2011 at 20:29 Comment(0)
D
27

Because the syntax of takewhile() and dropwhile() is not the clearest, here are the actual examples of your question:

>>> [i for i in itertools.takewhile(lambda x: x*x<30, range(10))]
[0, 1, 2, 3, 4, 5]
>>> [i for i in itertools.dropwhile(lambda x: x*x<30, range(10))]
[6, 7, 8, 9] 

Know that the author of itertools has questioned whether to deprecate these functions.

Digitate answered 30/8, 2011 at 4:57 Comment(4)
What would be the recipe in case these functions are deprecated?Seriatim
Just look at the Python docs for itertools.takewhile and itertools.dropwhile. Each has the straight Python equivalent.Digitate
isn't just list(itertools.takewhile(lambda x: x*x<30, range(10))) easier than a comprehension hereJeffreys
@Jeffreys I pointed the link at the same message, different host. ThanksDigitate
S
14

The various functions in itertools (takewhile() comes to mind) can help.

Samoyedic answered 31/3, 2011 at 20:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.