Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a description of how __cmp__ works for dict objects in Python 2?

Tags:

I've been trying to make a dict subclass inheriting from UserDict.DictMixin that supports non-hashable keys. Performance isn't a concern. Unfortunately, Python implements some of the functions in DictMixin by trying to create a dict object from the subclass. I can implement these myself, but I am stuck on __cmp__.

I cannot find a succinct description of the logic used by the built-in __cmp__ for the dict class.

like image 372
DannoHung Avatar asked Aug 14 '10 17:08

DannoHung


1 Answers

If you are asking how comparing dictionaries works, it is this:

  • To compare dicts A and B, first compare their lengths. If they are unequal, then return cmp(len(A), len(B)).
  • Next, find the key adiff in A that is the smallest key for which adiff not in B or A[adiff] != B[adiff]. (If there is no such key, the dicts are equal.)
  • Also find the smallest key bdiff in B for which bdiff not in A or A[bdiff] != B[bdiff].
  • If adiff != bdiff, then return cmp(adiff, bdiff). Else return cmp(A[adiff], B[bdiff]).

In pseudo-code:

def smallest_diff_key(A, B):     """return the smallest key adiff in A such that adiff not in B or A[adiff] != B[bdiff]"""     diff_keys = [k for k in A if k not in B or A[k] != B[k]]     return min(diff_keys)  def dict_cmp(A, B):     if len(A) != len(B):         return cmp(len(A), len(B))     try:         adiff = smallest_diff_key(A, B)     except ValueError:         # No difference.         return 0     bdiff = smallest_diff_key(B, A)     if adiff != bdiff:         return cmp(adiff, bdiff)     return cmp(A[adiff], b[bdiff]) 

This is translated from the 2.6.3 implementation in dictobject.c.

like image 105
Ned Batchelder Avatar answered Sep 27 '22 20:09

Ned Batchelder