Dict Copy & Compare

Steven D'Aprano steve at REMOVEME.cybersource.com.au
Tue May 1 23:23:30 EDT 2007


On Tue, 01 May 2007 08:14:53 -0500, Hamilton, William  wrote:

>> -----Original Message-----
>> From: Steven D'Aprano
>> Sent: Monday, April 30, 2007 10:14 PM
>> To: python-list at python.org
>> Subject: RE: Dict Copy & Compare
>> 
>> On Mon, 30 Apr 2007 12:50:58 -0500, Hamilton, William  wrote:
>> 
>> >> On quick question, how can I order a dict by the 'values' 
>> >> (not keys) before looping? Is that possible?
>> >>
>> >
>> > The easiest way I can think of is to create a new dict that's
>> > reversed.
>> >
>> > reverseDict = {}
>> > for key in dict1:
>> >     if dict1[key] not in reverseDict:
>> >         reverseDict[dict1[key]]=[key]
>> >     else:
>> >         reverseDict[dict1[key]].append(key)
>> >
>> > This gives you a dictionary that has the old dict's values as keys,
>> > and the old dict's keys as lists of values.  You can then sort the 
>> > keys of this dict and do what you want with it.  Of course, the
>> > values in dict1 have to be valid dictionary keys for this to work. 
>> > If they aren't, you may be able to get away with converting them to
>> > strings.
>> 
>> 
>> Oh man, maybe you need to re-think what you consider "easier".
>> 
>> for value in dict1.itervalues()
>>     do_something_with(value)
> 
> This iterates through a list of values, with no information about the
> keys at all.  Not particularly applicable to the OP's needs.

The OP asked for the values. You're just assuming he wants the values and
keys. Even if he does, my solution is the first step to having a better
understanding of what built-in methods Python dictionaries have, instead
of rolling his own sub-optimal solutions.



>> If you need the keys as well:
>> 
>> for key, value in dict1.iteritems()
>>     do_something_with(key, value)
> 
> This iterates through values and keys, in no particular order.  Still
> not useful.

And apart from being much faster, more readable and concise, and not
breaking if the values are lists or sets, how is my solution different
from your solution?

Hint: what order is your "reverse dictionary" in?


>> If you need to process the values (say, sort them) first:
>> 
>> pairs = list(dict1.iteritems()) # or dict1.items()
>> pairs.sort()
>> for key, value in pairs:
>>     do_something_with(key, value)
>> 
>> I'll leave sorting by value instead of key as an exercise.
> 
> Hrmm.  Maybe you missed the part where the OP was asking how to sort a
> dict's contents by value?  I'm pretty sure I quoted it.

Maybe you missed the part where I say "I'll leave sorting by value instead
of by key as an exercise". I'm pretty sure you quoted it.

I don't have to solve every last detail of the OP's problem for him, I
just need to point him in the right direction. The right direction is to
extract the key/items pairs and sort them whatever way he wants them. The
wrong solution is to stuff them into an unsorted dictionary, *then*
extract the keys and sort them whatever way he wants them.


> My bit of code would be better if I had used iteritems() (I hadn't come
> across that function yet).  But, it's a solution, 

No it isn't. It doesn't solve the question asked, and it spends far too
much effort (both programmer and CPU) to not solve it.


> and more useful than
> vague statements about what someone else needs to rethink and various
> bits of code that don't solve the problem presented.

They are not vague statements. Apart from the place-holder names
(do_something_with and dict1) you could copy and paste my examples into
an interactive session and have them work correctly. Your "solution"
doesn't even answer the OP's question, but merely builds an intermediate
data structure, leaving the actual solution up to him.

A vague statement would be your comment "Of course, the values
in dict1 have to be valid dictionary keys for this to work.  If they
aren't, you may be able to get away with converting them to strings." Now
that's vague.



-- 
Steven D'Aprano 




More information about the Python-list mailing list