I think there may be a simpler implementation, as shown below. It does pass the test cases given. Please take a look and kindly let me if anything is missing. TIA
def delete(self, key):
#find the node matching the key
p = self.head
while p:
if p.data == key: break
p = p.next
if p:
if not p.prev: #key at head
self.head = p.next
else:
p.prev.next = p.next
if not p.next: #key at tail
p.prev.next = None
else:
p.next.prev = p.prev
#else: key not found