On Tue, Jan 29, 2013 at 7:44 PM, Wolfgang Maier < wolfgang.maier@biologie.uni-freiburg.de> wrote:
list(i for i in range(100) if i<50 or stop()) Really (!) nice (and 2x as fast as using itertools.takewhile())!
I couldn't believe it so I had to check it: from __future__ import print_function import functools, itertools, operator, timeit def var1(): def _gen(): for i in range(100): if i > 50: break yield i return list(_gen()) def var2(): def stop(): raise StopIteration return list(i for i in range(100) if i <= 50 or stop()) def var3(): return [i for i in itertools.takewhile(lambda n: n <= 50, range(100))] def var4(): return [i for i in itertools.takewhile(functools.partial(operator.lt, 50), range(100))] if __name__ == '__main__': for f in (var1, var2, var3, var4): print(f.__name__, end=' ') print(timeit.timeit(f)) Results on my machine: var1 20.4974410534 var2 23.6218020916 var3 32.1543409824 var4 4.90913701057 var1 might have became the fastest of the first 3 because it's a special and very simple case. Why should explicit loops be slower that generator expressions? var3 is the slowest. I guess, because it has lambda in it. But switching to Python and back can not be faster than the last option - sitting in the C code as much as we can. -- Kind regards, Yuriy.