2016-06-14 7 views
0

Ich möchte die doppelt verknüpfte Struktur besser behandeln. Das Ziel in diesem Szenario besteht darin, einen Wertebereich an das Ende einer Liste anzuhängen. Ich würde dann gerne einen Wert testen, den ich in der Liste wissen sollte, dies sollte wahr werden, und umgekehrt für einen Wert, von dem ich weiß, dass er nicht in der Liste sein sollte. Also hier ist was ich bisher habe.Benutzerdefinierte "enthält" -Methode für die Liste

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

Test:

lst = LinkedList() 
    for i in range(100): 
     lst.append(i) 
    tc.assertFalse(100 in lst) 
    tc.assertTrue(50 in lst) 

Wenn ich diesen Code zu testen ich mir eine Assertion Fehler angezeigt bekommen sagen „Falsch ist nicht wahr“ Ich bin nicht sicher, warum mein Code 100, dass der Wert erkennen kann ist nicht in der Liste, obwohl es auch sagt, 50 ist nicht und gibt False zurück, wenn es True zurückgeben soll.

+0

jede statt alle verwenden. Außerdem brauchst du den Reißverschluss nicht. – Javier

Antwort

2

Ihre Implementierung ist falsch. Ihre -Funktion gibt nur dann true zurück, wenn alle Werte in Ihrer verknüpften Liste einem gegebenen Testwert entsprechen. I.e. es würde nur zutreffen, wenn alle Werte in verknüpften Liste miteinander auch gleich sind: Außerdem

>>> value = 'foo' 
>>> all(val1 == value for val1 in ['foo', 'bar', 'baz']) 
False 
>>> all(val1 == value for val1 in ['foo', 'foo', 'foo']) 
True 

, der zip() Aufruf in diesem Generator Ausdruck ist völlig überflüssig, Sie Paarung nicht auf Elemente aus mehrere iterables hier.

Verwenden Sie die any() function statt:

return any(v == value for v in self) 

all() nur zurückkehren, wenn Truealle Elemente im iterable wahr sind (es wird False zurückkehren früh). any() wird True zurück, sobald es findet jeder ein Element in der abzählbaren, die wahr ist:

>>> 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 
Verwandte Themen