Dict Copy & Compare

Robert Rawlins - Think Blue robert.rawlins at thinkbluemedia.co.uk
Mon Apr 30 08:46:09 EDT 2007


No that makes sense Tim,

Thanks again for all your help on this one, it'll all prove invaluable I'm
sure. I managed to crack all the big troubles last week with my reoccurring
tasks, it's just a case of tidying up a few of these loose ends, then
that'll be python project no.1 over and done with :-D

Thanks,

Rob

-----Original Message-----
From: python-list-bounces+robert.rawlins=thinkbluemedia.co.uk at python.org
[mailto:python-list-bounces+robert.rawlins=thinkbluemedia.co.uk at python.org]
On Behalf Of Tim Golden
Sent: 30 April 2007 12:54
Cc: python-list at python.org
Subject: Re: Dict Copy & Compare

Robert Rawlins - Think Blue wrote:
> On[e] quick question, how can I order a dict by 
 > the 'values' (not keys) before looping? Is that possible?

Depends on what you want to do. You can loop on
the sorted values very easily:

<code>
d1 = dict (a=2, b=1)
for value in sorted (d1.values):
   print value

</code>

but inferring the equivalent key is, in effect,
not possible since more than one key might correspond
to that value. Depending on what you're after, the
following technique might be of use:

<code>
import operator

d = dict (a=2, b=1, c=-1, d=4)
for k, v in sorted (
   d.items (),
   key=operator.itemgetter (1)
):
   print k, "=>", v

</code>

It may look a bit hairy, but break it down:

d.items () returns a list of 2-tuples, each one
corresponding to a key-value pair from the dict.
In our case, that'll be:

[('a', 2), ('b', 1), ('c', -1), ('d', 4)]

Although I've written them out like that,
the order they'll come in is undefined.

sorted () will return a sorted version of
whatever iterable you chuck at it. Under
normal Python semantics, sorted() on the
list above will return no change since I've
listed things out in alphanumeric order.

The extra key= parameter tells the sorted
routine to call the function you provide
against each of the items in the list (in
our case that means against each of the
2-tuples) and using the result of that
function as the sorting order.

The operation.itemgetter (1) bit is a touch
complicated unless you're already familiar with
partial functions, but it basically returns
*another* function which takes the item you
give it and returns the -- in this case --
1st item. Just believe me: it works.

So, in summary:

+ Get a list of key-value pairs
+ Sort them according to the 1st item (Python-style)
which in this case is the value.
+ Do something with the result

Before the key= param was introduced into
sort/sorted, people used to do the same thing
with what's often called DSU (short for
decorate-sort-undecorate), a technique which
here would look something like this:

items = d.items ()
sortable_items = [(i[1], i) for i in items]
sortable_items.sort ()
sorted_items = [i[-1] for i in sortable_items]

I mention this because (a) you still see it around
a fair bit and (b) there are occasions where it's
still useful, for example where a simple function
call can't really cope.

(Did I answer the question, or was I just rambling?)

TJG
-- 
http://mail.python.org/mailman/listinfo/python-list




More information about the Python-list mailing list