Pythonic infinite for loop?

Peter Otten __peter__ at web.de
Fri Apr 15 10:11:39 CEST 2011


Paul Rubin wrote:

> Chris Angelico <rosuav at gmail.com> writes:
>>> sentinel = object()
>>> seq = (dct.get('Keyword%d'%i,sentinel) for i in count(1))
>>> lst = list(takewhile(lambda x: x != sentinel, seq))
>>
>> If I understand this code correctly, that's creating generators,
>> right? It won't evaluate past the sentinel at all?
> 
> Right, it should stop after hitting the sentinel once.
> 
>> That might well be what I'm looking for. A bit ugly, but efficient and
>> compact. And I can bury some of the ugliness away.
> 
> It occurs to me, operator.ne might be a little faster than the
> interpreted lambda.

Or operator.is_not as you are dealing with a singleton. You also need 
functools.partial:

$ python -m timeit -s'sentinel = object(); predicate = lambda x: x != 
sentinel' 'predicate(None)'
1000000 loops, best of 3: 0.369 usec per loop

$ python -m timeit -s'sentinel = object(); predicate = lambda x: x is not 
sentinel' 'predicate(None)'
1000000 loops, best of 3: 0.314 usec per loop

$ python -m timeit -s'from functools import partial; from operator import 
ne; sentinel = object(); predicate = partial(ne, sentinel)' 
'predicate(None)'
1000000 loops, best of 3: 0.298 usec per loop

$ python -m timeit -s'from functools import partial; from operator import 
is_not; sentinel = object(); predicate = partial(is_not, sentinel)' 
'predicate(None)'
1000000 loops, best of 3: 0.252 usec per loop






More information about the Python-list mailing list