[Python-ideas] Syntax for key-value iteration over mappings

Nick Coghlan ncoghlan at gmail.com
Mon Jul 27 17:04:24 CEST 2015

On 27 July 2015 at 20:21, Stephen J. Turnbull <stephen at xemacs.org> wrote:
> Petr Viktorin writes:
>  > Currently, the way to iterate over keys and values of a mapping
>  > is to call items() and iterate over the resulting view::
>  >
>  >     for key, value in a_dict.items():
>  >         print(key, value)
>  >
>  > I believe that looping over all the data in a dict is a very imporant
>  > operation, and I find myself writing this quite often.
> Sure, but the obvious syntax:
>     for key, value in a_dict:
> is already taken: it unpacks the key if it happens to be a tuple.
> I've always idly wondered why iteration over a mapping was taken to be
> an iteration over keys rather than over items.  Idling just a little
> bit faster, I wonder if this isn't a throwback to the days when sets
> were emulated by dictionaries with constant value (eg, None).  I'm
> hard put to think of the last time I wanted to actually iterate over
> keys, doing something *other* than extracting the value.

Looking up the original iterator PEP shows it was done to enforce the
container invariant "for x in y: assert x in y".

So that has_key() -> __contains__() change came first, and drove the
subsequent selection of iterkeys() as the meaning of mapping

At least, that's my reading of the dictionary iterator section in

>  > In dict comprehensions and literals, key-value pairs are separated by
>  > colons. How about allowing that in for loops as well?
>  >
>  >     for key: value in a_dict:
>  >         print(key, value)
> This screams SyntaxError to me.  Sure, I can figure out what's meant,
> but the cognitive burden would be large every time I saw it.
> More generally, YMMV but I don't see any real point in adding syntax
> for this.

One point in favour is that many, many, years after ABCs were
introduced at least in part to disambiguate the Sequence and Mapping
APIs, we'd finally have a separate ducktyping protocol that was unique
to mappings :)

However, overall, I have to come down in the "-1" camp as well. With
dict comprehensions, the dict syntax changes the type of the object
produced, and matches the syntax of normal dict displays. In this
case, the colon is present without its surrounding curly braces, so
the prompts to think "dictionary" aren't as strong as they are in the
comprehension case. Embedding this novel iteration syntax in
comprehensions would make that confusion even worse.

Since there'd still be a method call under the hood, the new syntax
also wouldn't offer a performance benefit over calling the items()
method explicitly.

I actually quite liked the idea on a first impression, but it doesn't
appear to hold up to closer scrutiny.


Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia

More information about the Python-ideas mailing list