Should: "for k,v in **dictionary_instance" work?

Steven D'Aprano steve at REMOVE.THIS.cybersource.com.au
Fri Jun 15 22:27:02 EDT 2007


On Fri, 15 Jun 2007 19:17:25 +0000, keithgabryelski wrote:

> Does it make sense to provide this syntax for iterating key/value
> pairs from a dictionary?
> 
> for k,v in **dict():
>    print k,v
>
> why is this not the same as:
> 
> for k,v in dict().items():
>   print k,v

Because *t and **d already have well-defined meanings, and that's not
what **d would mean.

In a function definition, *t collects positional arguments into a tuple
and **d collects keyword arguments into a dictionary. In a function call,
they expand them again. For example:

function(1, 2, 3, a=4, b=5, c=6) 
==> t = (1, 2, 3); d = {'a':4, 'b':5, 'c':6}

function(*t, **d) 
==> function(1, 2, 3, a=4, b=5, c=6) 


Currently, *t and **d are syntax errors outside of function calls and
definitions. (Any other places?) But if they were allowed, what would they
mean? For consistency, we would expect the following:

t = tuple(1, 2, 3)
for item in *t:
    # same as "for item in 1, 2, 3:"
    print item


Even if it were allowed, it would be pointless: it would just expand the
tuple only to collect it again.

What would **d mean?

d = dict(a=1, b=2, c=3)
for key, value in **d:
    # same as "for key, value in 'a': 1, 'b': 2, 'c': 3:"
    print key, value


For starters, that would mean changing the syntax of Python to allow
key:value assignments outside of a dict constructor. I can't think of a
reason to do so, but even if there is, we have the same problem as for the
tuple expansion: it would pointlessly expand the dict, only to collect it
again.

Maybe you don't care about consistency and you just want the compiler to
accept "for k,v in **d" as syntactic sugar for "for k,v in d.items()". Or
perhaps d.iteritems() would be a better choice.

In that case, Python isn't very big on syntactic sugar merely for saving a
few characters of typing, so you're unlikely to convince those who would
need convincing.


> for that matter, why the heck doesn't a dictionary default to
> returning a tuple
> k,v pair from its iterator?

When dictionaries were first made iterable, in Python 2.2 if I recall
correctly, there was debate about whether "for thing in dict:" should be
equivalent to iterating over the keys, the values or both. In particular,
people pointed out that there were just as many, or slightly more,
examples of "for k,v in dict.items()" as "for k in dict.keys()" in the
standard library. So there is a good case for making iterating over a
dictionary equivalent to iterating over the keys and values.

But the deciding point was the correspondence between "for x in dict" and
"if x in dict". In fact, Python then, and now, included a fall-back
iterator protocol: if __getitem__ is defined, iteration over an object is
equivalent to repeatedly calling __getitem__.

You can read the PEP that covers some of these issues here:

http://svn.python.org/projects/peps/trunk/pep-0234.txt



-- 
Steven.




More information about the Python-list mailing list