yoav glazner <yoavglazner@...> writes:
Here is very similar version that works (tested on python27)
def stop():
next(iter([]))
list((i if i<50 else stop()) for i in range(100))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]
Joao S. O. Bueno <jsbueno@...> writes:
Great. I think this nails it. It is exactly the intended behavior, and very readable under current language capabilities.
One does not have to stop and go read what "itertools.takewhile" does, and mentally unfold the lambda guard expression - that is what makes this (and the O.P. request) more readable than using takewhile.
Note: stop can also just explictly raise StopIteration - or your next(iter([])) expression can be inlined within the generator.
It works in Python 3 as well - though for those who did not test: it won't work for list, dicr or set comprehensions - just for generator expressions.
Shane Green <shane@...> writes:
Here's what I was doing, and worked when i switched to the generator:
def stop():
… raise StopIteration()
list(((x if x < 5 else stop()) for x in range(10)))
[0, 1, 2, 3, 4]
Wow, thanks to the three of you! I think it's still not as clear what the code does as it would be with my 'while' suggestion. Particularly, the fact that this is not a simple 'if'-or-not decision for individual elements of the list, but in fact terminates the list with the first non-matching element (the while-like property) can easily be overlooked. However, I find it much more appealing to use built-in python semantics than to resort to the also hard to read itertools.takewhile(). In addition, this is also the fastest solution that was brought up so far. In my hands, it runs about 2x as fast as the equivalent takewhile construct, which in turn is just marginally faster than Boris Borcic's suggestion: |>>> def notyet(cond) : if cond : raise StopIteration return True
|>>> list(x for x in range(100) if notyet(x>10)) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
I guess, I'll use your solution in my code from now on. Best, Wolfgang