[Python-ideas] while conditional in list comprehension ??

Shane Green shane at umbrellacode.com
Wed Jan 30 02:56:36 CET 2013
Ah, right, feeding it through an iterator gives you full control…





Shane Green 
www.umbrellacode.com
408-692-4666 | shane at umbrellacode.com

On Jan 29, 2013, at 5:27 PM, Shane Green <shane at umbrellacode.com> wrote:

> Wait, it was much simpler than that…
> 
> >>> def until(items):
> ...     stops = []
> ...     def stop():
> ...             stops.append(1) 
> ...     yield stop
> ...     items = iter(items)
> ...     counter = 0
> ...     while not stops:
> ...             yield next(items)
> ...             print(counter)
> ...             counter += 1
> ... 
> >>> 
> >>> gen = until(range(15))
> >>> stop = next(gen)
> >>> [x for x in gen if x < 3 or stop()]
> 0
> 1
> 2
> 3
> [0, 1, 2]
> >>> 
> 
> 
> I must have just been up for too long that this looks like something new to me.
> 
> 
> 
> Shane Green 
> www.umbrellacode.com
> 408-692-4666 | shane at umbrellacode.com
> 
> On Jan 29, 2013, at 3:37 PM, Yuriy Taraday <yorik.sar at gmail.com> wrote:
> 
>> On Tue, Jan 29, 2013 at 7:44 PM, Wolfgang Maier <wolfgang.maier at 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.
>> _______________________________________________
>> Python-ideas mailing list
>> Python-ideas at python.org
>> http://mail.python.org/mailman/listinfo/python-ideas
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20130129/c7eb03a8/attachment.html>


More information about the Python-ideas mailing list