[Tutor] list of dicts <-> dict of lists?

Steven D'Aprano steve at pearwood.info
Fri May 28 02:51:01 CEST 2010


On Fri, 28 May 2010 09:19:20 am Matthew Wood wrote:

> I BELIEVE there's some new cool features in 2.6 or maybe 3.0 where
> non-simultaneous access to my_dict.keys() and my_dict.values() will
> keep them "paired up", but I don't know the details.

This is not a new feature, but a very old feature. It became a 
guaranteed promise of the language in Python 2.0:

http://docs.python.org/release/2.0/lib/typesmapping.html

and worked at least back to Python 1.5:

[steve at sylar ~]$ python1.5
Python 1.5.2 (#1, Apr  1 2009, 22:55:54)  [GCC 4.1.2 20070925 (Red Hat 
4.1.2-27)] on linux2
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> d = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
>>> # mess with the dict a little bit
... d['a'] = -1
>>> d['f'] = -1
>>> del d['a']
>>> d['f'] = 6
>>> d['a'] = 1
>>> print d
{'f': 6, 'd': 4, 'e': 5, 'b': 2, 'c': 3, 'a': 1}
>>> d.keys()
['f', 'd', 'e', 'b', 'c', 'a']
>>> d.values()
[6, 4, 5, 2, 3, 1]


Since this is guaranteed, your comment:

> # This line isn't necessary #keys, values = zip(* y.items())
...
> But since I'm a coward, and I'd like my code to run on older versions
> of python too, I'd leave the initial step.

is unfortunately cargo-cult programming (programming without 
understanding what you are doing). This sounds bad, and it is, but 
we've all been there and done that, so don't take offence.

Firstly, it's not necessary, and secondly, even if it was necessary, it 
won't work in older versions:

>>> keys, items = zip(*d.items())
  File "<stdin>", line 1
    keys, items = zip(*d.items())
                      ^
SyntaxError: invalid syntax


So drop it. You either trust Python, or you don't, and if you don't, you 
can't trust it to do *anything*. (If d.keys() and d.values() are buggy, 
how do you know that zip() or d.items() aren't buggy too?)

The exception to this is if you are handling non-dict mappings that 
don't make promises about keeping d.keys() and d.values() aligned in 
order. And that requires a comment to show why you're doing what 
otherwise would seen to be unnecessary work:

# Support badly-behaved mappings like mymodule.stupid_dict.
keys, items = zip(*d.items())
...

rather than:

# Appease the Python gods so they give us cargo and not bugs.
keys, values = zip(d.items())
...


See the difference between cargo cult programming and defensive 
programming?





-- 
Steven D'Aprano


More information about the Tutor mailing list