title: itertools.islice implementation -- efficiently slicing a list
body: <p>Earlier, I was trying to answer a question where I wanted to iterate over a list slice as efficiently as possible.</p>
  
  <pre><code>for x in lst[idx1:]:
  </code></pre>
  
  <p>isn't ideal as it creates a copy (In general, this is <code>O(n)</code>).  My next thought was to use <a href="http://docs.python.org/2/library/itertools.html#itertools.islice" rel="noreferrer"><code>itertools.islice</code></a>.  But if you look at the documentation, it appears that <code>islice</code> will call <code>next</code> until it finds the index it is looking for at which point it will start to yield values.  This is also <code>O(n)</code>.  It seems that there is an optimization that is available here if the object passed to <code>islice</code> is a <code>list</code> or a <code>tuple</code> -- It seems that you could iterate over the "slice" directly (in C) without actually making a copy.  I was curious if this optimization is in <a href="http://hg.python.org/cpython/file/efedd0f62a7e/Modules/itertoolsmodule.c#l1370" rel="noreferrer">the source</a>, But I didn't find anything.  I'm not extremely familiar with C and the python source tree, so it's entirely possible that I missed it.</p>
  
  <p>My question is this:</p>
  
  <blockquote>
    <p>Is there a way to iterate over a list "slice" without making a copy of the list slice and without burning through a bunch of unwanted elements (in an optimized C implementation)?</p>
  </blockquote>
  
  <p>I'm well aware that I could write my own generator for this (very naively, not accounting for the fact that many of the arguments should be optional, etc.):</p>
  
  <pre><code>def myslice(obj,start,stop,stride):
      for i in xrange(start,stop,stride):
          yield obj[i]
  </code></pre>
  
  <p>but that's definitely not going to beat an optimized C implementation.</p>
  
  <hr>
  
  <p>If you're wondering why I would need this over just looping over a slice directly, consider the difference between:</p>
  
  <pre><code>takewhile(lambda x: x == 5, lst[idx:])  #copy's the tail of the list unnecessarily
  </code></pre>
  
  <p>and</p>
  
  <pre><code>takewhile(lambda x: x == 5, islice(lst,idx,None)) #inspects the head of the list unnecessarily 
  </code></pre>
  
  <p>and finally:</p>
  
  <pre><code>takewhile(lambda x: x == 5, magic_slice(lst,idx,None)) #How to create magic_slice???
  </code></pre>