<div dir="ltr"><div class="gmail_quote"><div dir="ltr">On Tue, 7 Jul 2015 at 13:34 Steven D'Aprano <<a href="mailto:steve@pearwood.info">steve@pearwood.info</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Tue, Jul 07, 2015 at 12:59:07AM -0700, Kale Kundert wrote:<br>
<br>
> 3. Readability counts, and those expressions hide the intent of the programmer.<br>
>  You wouldn't use 'next(iter(o))' to access the first element of a list, because<br>
> that would be confusing and obfuscated.<br>
<br>
I agree with all of those objections, especially the third. Which is why<br>
the reasonable and simple solution is to write:<br>
<br>
def first(od):<br>
    return next(iter(od))<br>
<br>
def last(od):<br>
    return next(reversed(od))<br>
<br>
then call first(o), last(o). Add comments, documentation and tests to<br>
taste. Or subclass OrderedDict and add first() last() methods.<br></blockquote><div><br></div><div>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:<br><br></div><div>def first(od):<br></div><div>    try:<br></div><div>        return next(iter(od))<br></div><div>    except StopIteration:<br></div><div>        raise KeyError<br></div><div> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I am unconvinced that peeking at the first and last items of a dict<br>
(ordered, sorted or otherwise), let alone O(1) indexed access to items,<br>
is a good fit for the OrderedDict API. If I were the OD maintainer, I<br>
would want to understand your use-case (why are you using an OD as a<br>
queue, instead of a list, deque, or queue?), and possibly hear two or<br>
three additional uses, before agreeing to add it to the API.<br></blockquote><div><br></div><div>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.<br><br>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:<br><br></div><div>def peekitem(od):<br></div><div>    key, val = od.popitem()<br></div><div>    od[key] = val<br></div><div>    return key, val<br><br>--<br></div><div>Oscar<br></div></div></div>