[Python-Dev] I'd like list.pop to accept an optional second argument giving a defaultvalue

Tim Peters tim_one@email.msn.com
Fri, 23 Jul 1999 03:23:27 -0400


In a moment of insanity, Guido gave me carte blanche to suggest new list
methods, and list.pop & list.extend were the result.  I considered spec'ing
list.pop to take an optional "default on bad index" argument too, but after
playing with it didn't like it (always appeared just as easy & clearer to
use "if list:" / "while list:" etc).

Jim has a novel use I hadn't considered:

> With pop, you can essentially test whether the list is
> empty and get a value if it isn't in one atomic operation:
>
>   try:
>       foo=queue.pop(0)
>   except IndexError:
>       ... empty queue case
>   else:
>       ... non-empty case, do something with foo
>
> Unfortunately, this incurs exception overhead. I'd rather do
> something like:
>
>   foo=queue.pop(0,marker)
>   if foo is marker:
>       ... empty queue case
>   else:
>       ... non-empty case, do something with foo

It's both clever and pretty.  OTOH, the original try/except isn't expensive
unless the "except" triggers frequently, in which case (the queue is often
empty) a thread is likely better off with a yielding Queue.get() call.

So this strikes me as useful only for thread micro-optimization, and a kind
of optimization most users should be steered away from anyway.  Does anyone
have a real use for this outside of threads?  If not, I'd rather it not go
in.

For threads that need an optimized non-blocking probe, I'd write it:

    gotone = 0
    if queue:
        try:
            foo = queue.pop(0)
            gotone = 1
        except IndexError:
            pass
    if gotone:
        # use foo
    else:
        # twiddle thumbs

For the IndexError to trigger there, a thread has to lose its bytecode slice
between a successful "if queue" and the queue.pop, and not get another
chance to run until other threads have emptied the queue.