dictionary interface

Bengt Richter bokr at oz.net
Thu Oct 6 03:15:17 EDT 2005


On 5 Oct 2005 08:23:53 GMT, Antoon Pardon <apardon at forel.vub.ac.be> 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.
>
"other outcomes" may not in general mean orderings are defined,
even when  ==  and != are well defined. E.g., below

>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.
>
A couple of data points that may be of interest:

 >>> {'a':0j} < {'a':1j}
 Traceback (most recent call last):
   File "<stdin>", line 1, in ?
 TypeError: cannot compare complex numbers using <, <=, >, >=

and
 >>> cmp(0j, 1j)
 Traceback (most recent call last):
   File "<stdin>", line 1, in ?
 TypeError: cannot compare complex numbers using <, <=, >, >=

but
 >>> {'a':0j} == {'a':1j}
 False
 >>> {'a':1j} == {'a':1j}
 True

Regards,
Bengt Richter



More information about the Python-list mailing list