【问题标题】:How to write equals method如何编写equals方法
【发布时间】:2016-06-14 05:30:24
【问题描述】:

情况:我正试图很好地处理双链接结构。到目前为止,我已经很好地掌握了这些方法。我希望能够为此类创建两个对象并检查其中的每个项目是否相等。我没有任何语法错误,而且我得到的错误有点令人困惑。这就是我目前所拥有的。

class LinkedList:
    class Node:
        def __init__(self, val, prior=None, next=None):
            self.val = val
            self.prior = prior
            self.next  = next

    def __init__(self):
        self.head = LinkedList.Node(None) # sentinel node (never to be removed)
        self.head.prior = self.head.next = self.head # set up "circular" topology
        self.length = 0

    def append(self, value):
        n = LinkedList.Node(value, prior=self.head.prior, next=self.head)
        n.prior.next = n.next.prior = n
        self.length += 1

    def _normalize_idx(self, idx):
        nidx = idx
        if nidx < 0:
            nidx += len(self)
            if nidx < -1:
                raise IndexError  
        return nidx

    def __getitem__(self, idx):
        """Implements `x = self[idx]`"""
        nidx = self._normalize_idx(idx)
        currNode = self.head.next
        for i in range(nidx):
            currNode = currNode.next
        if nidx >= len(self):
            raise IndexError
        return currNode.val


    def __setitem__(self, idx, value):
        """Implements `self[idx] = x`"""
        nidx = self._normalize_idx(idx)
        currNode = self.head.next
        if nidx >= len(self):
            raise IndexError
        for i in range(nidx):
            currNode = currNode.next
        currNode.val = value

    def __iter__(self):
        """Supports iteration (via `iter(self)`)"""
        cursor = self.head.next
        while cursor is not self.head:
            yield cursor.val
            cursor = cursor.next

    def __len__(self):
        """Implements `len(self)`"""
        return self.length

    def __eq__(self, other):
        currNode = self.head.next
        currNode2 = other.head.next
        for currNode, currNode2 in zip(self, other):
            if currNode.val != currNode2.val:
                return False
        return True

测试:

from unittest import TestCase
tc = TestCase()
lst = LinkedList()
lst2 = LinkedList()

tc.assertEqual(lst, lst2)

lst2.append(100)
tc.assertNotEqual(lst, lst2)

当我测试此代码时,我得到一个断言错误,说“[] == [100]”我不确定为什么我的代码将其识别为相等,而我希望它实际检查节点中的特定值。

【问题讨论】:

    标签: python linked-list


    【解决方案1】:

    zip 只到达最短的列表。你想要itertools.zip_longest,而不想要.val(你的迭代器已经返回了实际值)。试试这个:

    def __eq__(self, other):
        for val1, val2 in zip_longest(self, other):
            if val1 != val2:
                return False
        return True
    

    或者更好?

    def __eq__(self, other):
        return all(val1 == val2 for val1, val2 in zip_longest(self, other))
    

    编辑

    我喜欢@BrenBarn 建议先检查长度。这是一个更有效的答案:

    def __eq__(self, other):
        return len(self) == len(other) and all(
            val1 == val2 for val1, val2 in zip(self, other))
    

    【讨论】:

    • 这个特殊的 LinkedList 似乎存储了它的长度,所以长度检查是 O(1)。
    • 注意到我写评论的那一刻,并删除了它。
    【解决方案2】:

    zip(self.other) 只为您提供与两个列表中较短者一样多的元素。它丢弃较长列表的额外部分。所以对于[] == [100]zip 不提供任何元素,并且您的代码返回 True 而不检查任何内容。

    您可以在开始时检查列表是否有不同的长度。如果他们这样做,他们就不可能平等。

    【讨论】:

      猜你喜欢
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      • 2023-02-22
      • 1970-01-01
      • 1970-01-01
      • 2011-11-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多