dictionary interface

Steve Holden steve at holdenweb.com
Wed Oct 5 05:05:22 EDT 2005


Antoon Pardon wrote:
> Op 2005-10-05, Tom Anderson schreef <twic at urchin.earth.li>:
> 
>>On Tue, 4 Oct 2005, Robert Kern wrote:
>>
>>
>>>Antoon Pardon wrote:
>>>
>>>
>>>>  class Tree:
>>>>
>>>>    def __lt__(self, term):
>>>>      return set(self.iteritems()) < set(term.iteritems())
>>>>
>>>>    def __eq__(self, term):
>>>>      return set(self.iteritems()) == set(term.iteritems())
>>>>
>>>>Would this be a correct definition of the desired behaviour?
>>>
>>>No.
>>>
>>>In [1]: {1:2} < {3:4}
>>>Out[1]: True
>>>
>>>In [2]: set({1:2}.iteritems()) < set({3:4}.iteritems())
>>>Out[2]: False
>>>
>>>
>>>>Anyone a reference?
>>>
>>>The function dict_compare in dictobject.c .
>>
>>Well there's a really helpful answer. I'm intrigued, Robert - since you 
>>know the real answer to this question, why did you choose to tell the 
>>Antoon that he was wrong, not tell him in what way he was wrong, certainly 
>>not tell him how to be right, but just tell him to read the source, rather 
>>than simply telling him what you knew? Still, at least you told him which 
>>file to look in. And if he knows python but not C, or gets lost in the 
>>byzantine workings of the interpreter, well, that's his own fault, i 
>>guess.
>>
>>So, Antoon, firstly, your implementation of __eq__ is, i believe, correct.
>>
>>Your implementation of __lt__ is, sadly, not. While sets take "<" to mean 
>>"is a proper subset of", for dicts, it's a more conventional comparison 
>>operation, which constitutes a total ordering over all dicts (so you can 
>>sort with it, for example). However, since dicts don't really have a 
>>natural total ordering, it is ever so slightly arbitrary.
>>
>>The rules for ordering on dicts are, AFAICT:
>>
>>- If one dict has fewer elements than the other, it's the lesser
>>- If not, find the smallest key for which the two dicts have different 
>>values (counting 'not present' as a value)
>>-- If there is no such key, the dicts are equal
>>-- If the key is present in one dict but not the other, the dict in which 
>>it is present is the lesser
>>-- Otherwise, the dict in which the value is lesser is itself the lesser
>>
>>In code:
>>
>>def dict_cmp(a, b):
>> 	diff = cmp(len(a), len(b))
>> 	if (diff != 0):
>> 		return diff
>> 	for key in sorted(set(a.keys() + b.keys())):
>> 		if (key not in a):
>> 			return 1
>> 		if (key not in b):
>> 			return -1
>> 		diff = cmp(a[key], b[key])
>> 		if (diff != 0):
>> 			return diff
>> 	return 0
>>
> 
> 
> Thanks for the explanation, but you somehow give me too much.
> 
> I have been searching some more and finally stumbled on this:
> 
> http://docs.python.org/ref/comparisons.html
> 
>   Mappings (dictionaries) compare equal if and only if their sorted
>   (key, value) lists compare equal. Outcomes other than equality are
>   resolved consistently, but are not otherwise defined.
> 
> This seems to imply that the specific method to sort the dictionaries
> is unimported (as long as it is a total ordering). So I can use whatever
> method I want as long as it is achieves this.
> 
> But that is contradicted by the unittest. If you have a unittest for
> comparing dictionaries, that means comparing dictionaries has a
> testable characteristic and thus is further defined.
> 
> So I don't need a full implementation of dictionary comparison,
> I need to know in how far such a comparison is defined and
> what I can choose.
> 
The dict unit tests are probably trying to ensure that the dictionary 
ordering doesn't change from version to version, which is probably a 
good idea in case someone (foolishly?) deciess to rely on it.

I can't help wondering, though, under what conditions it actually makes 
sense to compare two dictionaries for anything other than equality.

regards
  Steve
-- 
Steve Holden       +44 150 684 7255  +1 800 494 3119
Holden Web LLC                     www.holdenweb.com
PyCon TX 2006                  www.python.org/pycon/




More information about the Python-list mailing list