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

Petr Viktorin encukou at gmail.com
Sun Jul 26 18:09:17 CEST 2015

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. Every time I do,
it seems it's boilerplate; it looks a like a workaround rather than a
preferred way of doing things.

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)

I argue that to anyone familiar with dict literals, let alone dict
comprehensions, the semantics of this loop should be pretty obvious.
In dict comprehensions, similarity to existing syntax becomes even
more clear:

    a_mapping = {1: 'one', 2: 'two'}
    inverse = {val: key for key: val in a_mapping}

I've bounced this idea off a few EuroPython sprinters, and got some
questions/concerns I can answer here:

* But, the colon is supposed to start a block!

Well, it's already used in dict comprehensions/literals (though it's
true that there it's always inside brackets). And in lambdas –
Here's code that is legal today (though not very practical):

    while lambda: True:

* There's supposed to be only one obvious way to do it! We alredy have .items()!

I don't think this stops us from adding a new way of doing things which
is more obvious than the old, and which should become the one way.
After all, you don't say "for key in mapping.keys():", even though
the keys() method exists.

* What exactly would it do?

There are multiple options —
- loop over .keys() and use __getitem__ each time, like the
  dict() constructor?
- loop over .items(), like most of the code used today?
- become a well-specified "key/value iteration protocol" with
  __iteritems__() and its own bytecode operation?

— but here I'm asking if building this bikeshed sounds useful, rather
than what paint to buy.

That said, I do have a proof of concept implementation of the second
option, in case you'd like to play around with this:
Github: https://github.com/encukou/cpython/tree/keyval-iteration
patch: https://github.com/encukou/cpython/commit/b9b0d973342280f0ef52e26a4b67f326ece82a54.patch

More information about the Python-ideas mailing list