Есть ли описание того, как __cmp__ работает для объектов dict в Python 2? - PullRequest
20 голосов
/ 14 августа 2010

Я пытался создать подкласс dict, унаследованный от UserDict.DictMixin, который поддерживает не хэш-ключи. Производительность не проблема. К сожалению, Python реализует некоторые функции в DictMixin, пытаясь создать объект dict из подкласса. Я могу реализовать это сам, но я застрял на __cmp__.

Я не могу найти краткое описание логики, используемой встроенным __cmp__ для класса dict.

Ответы [ 3 ]

30 голосов
/ 14 августа 2010

Если вы спрашиваете, как работает сравнение словарей, это так:

  • Чтобы сравнить диктанты A и B, сначала сравните их длины.Если они неравны, верните cmp (len (A), len (B)).
  • Затем найдите adiff ключа в A, который является наименьшим ключом, для которого adiff not in B or A[adiff] != B[adiff].(Если такого ключа не существует, значения будут одинаковыми.)
  • Также найдите наименьший ключ bdiff в B, для которого bdiff not in A or A[bdiff] != B[bdiff].
  • Если adiff! = Bdiff, вернуть cmp (адифф, бдифф).Иначе return cmp (A [adiff], B [bdiff]).

В псевдокоде:

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])

Это переводится из реализации 2.6.3 в dictobject.с.

2 голосов
/ 14 августа 2010

Альтернативой является использование Mapping ABC из пакета collection .Это доступно в 2.6 и выше.Вы просто наследуете от коллекций. Сопоставление и реализация методов __getitem__, __contains__ и __iter__.Вы получаете все остальное бесплатно.

0 голосов
/ 14 августа 2010

Здесь есть описание __cmp__ здесь , но я думаю, что важно отметить, что __cmp__ используется только в том случае, если методы «богатого сравнения», такие как __lt__ и __eq__ не определены.Более того, в Python3 __cmp__ удалено из языка.Так что, возможно, полностью исключите __cmp__ и просто определите __lt__ и __eq__.

...