[Python-ideas] Syntax for key-value iteration over mappings
Rob Cliffe
rob.cliffe at btinternet.com
Mon Jul 27 03:52:29 CEST 2015
On 26/07/2015 17:09, Petr Viktorin wrote:
> Hello,
> 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:
> break
>
> * 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.
You just might, if you modified the dictionary in the loop body, and you
wanted to process the original list of keys but didn't need to remember
the original values and wanted to avoid the overhead of copying the values.
>
> * 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.
I like it! It seems so intuitive that, like Sven, I wonder why it's not
already in the language.
As far as I can see it doesn't introduce any ambiguities. I am thinking
of code such as
for k,j : x,(y,z), in complicated_expression:
I would guess (from a position of complete ignorance) that there would
be no *insuperable* difficulty in parsing this.
I suggest (without feeling strongly about it) that optional parentheses
should be allowed for stylistic reasons, i.e.
for ( k : v ) in a_dict:
[I thought about
for { k : v } in a_dict:
before I realised that this is currently legal, albeit (probably)
nonsensical, syntax. [Python 2.7.3]]
One downside: Whatever implementation is chosen, it will not be "the one
obvious way to do it".
E.g. an .iteritems()-like implementation will fail if the dictionary is
modified during the loop.
an .items()-like implementation will be expensive on a huge
dictionary.
As there are already several ways of iterating over a dictionary, I
think the new construct should be semantically equivalent to one of the
existing ways, so that we don't have yet another behaviour to learn. My
bikeshed colour is that it be equivalent to using .items(), as I think
this is least likely to trip up newbies (it won't raise an error if the
dictionary is modified); YMMV.
Rob Cliffe
>
> 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
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
> -----
> No virus found in this message.
> Checked by AVG - www.avg.com
> Version: 2014.0.4821 / Virus Database: 4365/10312 - Release Date: 07/26/15
More information about the Python-ideas
mailing list