array next pointer

R. David Murray rdmurray at bitdance.com
Wed Mar 18 11:59:23 EDT 2009


Duncan Booth <duncan.booth at invalid.invalid> wrote:
> Armin <feng.shaun at gmail.com> wrote:
> 
> > Could you give an example of next() with a sentinel and describe its
> > use case please?  I have a little trouble understanding what you guys
> > mean! 
> 
> It means you don't have to worry about next() throwing StopIteration. 
> 
> e.g.
> >>> def pairs(sequence, padding=None):
> 	sequence = iter(sequence)
> 	for a in sequence:
> 		b = next(sequence, padding)
> 		yield a, b
> 
> 		
> >>> list(pairs('abcd'))
> [('a', 'b'), ('c', 'd')]
> >>> list(pairs('abcde'))
> [('a', 'b'), ('c', 'd'), ('e', None)]

That's using the next parameter for its primary purpose: supplying a default.
The sentinel sub-case might be something like this:

    SENTINEL = object()
    while somecondition:
        #do something
        val = next(someiterator, SENTINEL)
        if val is SENTINEL: break
        #do something with val

In most cases you'd refactor code like that into a generator or something,
but there are cases where a pattern like the above can be useful.  The
idea is that next will only return SENTINEL when the iterator is exhausted.
If you didn't use the SENTINEL, then StopIteration would be raised.  So you
could write the above as:

        try: val = next(someiterator)
        except StopIteration: break

but the version using SENTINEL avoids having the interpreter do the work
of generating a traceback, and is IMO slightly prettier.

I'm sure there are other use cases, too, but probably not a huge number
of them.  Certainly not as many as using the parameter as a default.

--
R. David Murray           http://www.bitdance.com




More information about the Python-list mailing list