title: Why are __getitem__(key) and get(key) significantly slower than [key]?
body: <p>It was my understanding that brackets were nothing more than a wrapper for <code>__getitem__</code>.  Here is how I benchmarked this:</p>
  
  <p>First, I generated a semi-large dictionary.</p>
  
  <pre><code>items = {}
  for i in range(1000000):
      items[i] = 1
  </code></pre>
  
  <p>Then, I used cProfile to test the following three functions:</p>
  
  <pre><code>def get2(items):
      for k in items.iterkeys():
          items.get(k)
  
  def magic3(items):
      for k in items.iterkeys():
          items.__getitem__(k)
  
  def brackets1(items):
      for k in items.iterkeys():
          items[k]
  </code></pre>
  
  <p>The results looked like so:</p>
  
  <pre><code>         1000004 function calls in 3.779 CPU seconds
  
     Ordered by: standard name
  
     ncalls  tottime  percall  cumtime  percall filename:lineno(function)
          1    0.000    0.000    3.779    3.779 &lt;string&gt;:1(&lt;module&gt;)
          1    2.135    2.135    3.778    3.778 dict_get_items.py:15(get2)
          1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
    1000000    1.644    0.000    1.644    0.000 {method 'get' of 'dict' objects}
          1    0.000    0.000    0.000    0.000 {method 'iterkeys' of 'dict' objects}
  
  
           1000004 function calls in 3.679 CPU seconds
  
     Ordered by: standard name
  
     ncalls  tottime  percall  cumtime  percall filename:lineno(function)
          1    0.000    0.000    3.679    3.679 &lt;string&gt;:1(&lt;module&gt;)
          1    2.083    2.083    3.679    3.679 dict_get_items.py:19(magic3)
    1000000    1.596    0.000    1.596    0.000 {method '__getitem__' of 'dict' objects}
          1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
          1    0.000    0.000    0.000    0.000 {method 'iterkeys' of 'dict' objects}
  
  
           4 function calls in 0.136 CPU seconds
  
     Ordered by: standard name
  
     ncalls  tottime  percall  cumtime  percall filename:lineno(function)
          1    0.000    0.000    0.136    0.136 &lt;string&gt;:1(&lt;module&gt;)
          1    0.136    0.136    0.136    0.136 dict_get_items.py:11(brackets1)
          1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
          1    0.000    0.000    0.000    0.000 {method 'iterkeys' of 'dict' objects}
  </code></pre>
  
  <p>Is the issue in the way I am benchmarking?  I tried replacing the bracket access with a simple "pass" to ensure that the data was actually being accessed, and found that "pass" was running much quicker.  My interpretation of this was that the data was indeed being accessed.  I've also tried appending to a new list, which gave similar results.</p>