我希望更好地处理双重链接结构。此方案的目标是将一系列值附加到列表的末尾。然后我想测试一个我知道应该在列表中的值,这应该返回true,反之亦然,我知道该值不应该在列表中。所以这就是我迄今所拥有的。
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):
return len(self) == len(other) and all(
val1 == val2 for val1, val2 in zip(self, other))
def __contains__(self, value):
"""Implements `val in self`. Returns true if value is found in this list."""
return all(val1 == value for val1 in zip(self))
测试:
lst = LinkedList()
for i in range(100):
lst.append(i)
tc.assertFalse(100 in lst)
tc.assertTrue(50 in lst)
当我测试这段代码时,我得到一个Assertion错误,说&#34;错误不是真的&#34;我不确定为什么我的代码能够识别出值100不在列表中,而它也表示50不是,并且当它应该返回True时返回False。
答案 0 :(得分:2)
您的实施是错误的。如果链接列表中的所有值等于给定的测试值,则__contains__
函数仅返回true。即只有当您的链接列表中的所有值彼此相等时,它才会成立以及:
>>> value = 'foo'
>>> all(val1 == value for val1 in ['foo', 'bar', 'baz'])
False
>>> all(val1 == value for val1 in ['foo', 'foo', 'foo'])
True
此外,该生成器表达式中的zip()
调用完全是多余的,您不会在此处对多个迭代中的元素进行配对。
改为使用any()
function:
return any(v == value for v in self)
all()
只有在迭代中的所有项都为真时才会返回True
(它会提前返回False
)。 any()
只要在迭代中找到任何一个项目,就会返回True
:
>>> any(val1 == value for val1 in ['foo', 'bar', 'baz'])
True
>>> any(val1 == value for val1 in ['foo', 'foo', 'foo'])
True
>>> any(val1 == value for val1 in ['spam', 'bar', 'baz'])
False