HashMap Implementation (dictionary) in Python
Your implementation of get is wrong. The code is:

def get(self, key):
        address = self._hash(key)
        bucket = self.data[address]
        if bucket:
            while bucket[2] != None or key != bucket[0]:
                bucket = bucket[2]
            if bucket:
                return bucket[1]
        raise KeyError


The line while bucket[2] != None or key != bucket[0] says "keep traversing the link list as long as it's possible to do so, and if it's impossible, try to do it anyway if the key is wrong". Because of the boolean or, the condition bucket[2] != None means the loop will always step forward in the linked list if it's possible to do so - even if the current key is correct. On top of that, once the loop gets to the last element, if the key at that position does not match the given key, the loop will attempt to iterate once more, giving us:

TypeError                                 Traceback (most recent call last)
&lt;ipython-input-7-a5939dc0e83e&gt; in &lt;module&gt;()
----&gt; 1 h.get("apple")

&lt;ipython-input-1-4777e6d3506b&gt; in get(self, key)
     31         bucket = self.data[address]
     32         if bucket:
---&gt; 33             while bucket[2] != None or key != bucket[0]:
     34                 bucket = bucket[2]
     35             if bucket:

TypeError: 'NoneType' object is not subscriptable


The result is get fails with this error in every case except when the requested key is the last one in its slot.

The correct condition is of course while bucket[2] != None and key != bucket[0]. We then need to check afterwards that we got out of the loop because we found the right key, not because we ran out of buckets, giving us the implementation:

def get(self, key):
        address = self._hash(key)
        bucket = self.data[address]
        if bucket:
            while bucket[2] != None and key != bucket[0]:
                bucket = bucket[2]
            if bucket[0] == key:
                return bucket[1]
        raise KeyError