[Python-ideas] OrderedDict.peekitem()

Oscar Benjamin oscar.j.benjamin at gmail.com
Tue Jul 7 16:35:47 CEST 2015


On Tue, 7 Jul 2015 at 13:34 Steven D'Aprano <steve at pearwood.info> wrote:

> On Tue, Jul 07, 2015 at 12:59:07AM -0700, Kale Kundert wrote:
>
> > 3. Readability counts, and those expressions hide the intent of the
> programmer.
> >  You wouldn't use 'next(iter(o))' to access the first element of a list,
> because
> > that would be confusing and obfuscated.
>
> I agree with all of those objections, especially the third. Which is why
> the reasonable and simple solution is to write:
>
> def first(od):
>     return next(iter(od))
>
> def last(od):
>     return next(reversed(od))
>
> then call first(o), last(o). Add comments, documentation and tests to
> taste. Or subclass OrderedDict and add first() last() methods.
>

If the OrderedDict is empty both of the above will raise StopIteration.
This can have unintended consequences if the OrderedDict is called from
another iterator/generator etc. So it should probably be:

def first(od):
    try:
        return next(iter(od))
    except StopIteration:
        raise KeyError


> I am unconvinced that peeking at the first and last items of a dict
> (ordered, sorted or otherwise), let alone O(1) indexed access to items,
> is a good fit for the OrderedDict API. If I were the OD maintainer, I
> would want to understand your use-case (why are you using an OD as a
> queue, instead of a list, deque, or queue?), and possibly hear two or
> three additional uses, before agreeing to add it to the API.
>

I once wanted to be able to peek the last item. My usecase was something to
do with traversing a graph. Perhaps a depth-first search where I wanted a
stack of the vertices I was traversing and an efficient way to check for a
vertex in the stack (to avoid traversing cycles). I think the keys were the
vertices and the values were iterators over the neighbours of the
corresponding vertices.

After traversing all neighbours of a vertex I want to pop that vertex off
and continue traversing the vertex preceding it on the stack. I can
retrieve the vertex from the top of the stack with popitem. However I want
the returned vertex to remain in the stack while traversing its other
neighbours so I pop it off and then push it back on again akin to:

def peekitem(od):
    key, val = od.popitem()
    od[key] = val
    return key, val

--
Oscar
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20150707/2c9e49a3/attachment.html>


More information about the Python-ideas mailing list