title: Copying iterators in Python
body: <p>When you make a (shallow) copy of an iterator, it returns a new iterator.</p>
  
  <pre class="lang-py prettyprint-override"><code>from copy import copy
  
  
  data = [1, 2, 3, 4]
  
  iter1 = iter(data)
  iter2 = copy(iter1)
  
  [i for i in iter1]    #[1, 2, 3, 4]
  [i for i in iter2]    #[1, 2, 3, 4]
  </code></pre>
  
  <p>When you make a shallow copy of an iterator created with itertools, it returns the same iterator, but deepcopy returns a new one.</p>
  
  <pre class="lang-py prettyprint-override"><code>from copy import copy, deepcopy
  from itertools import takewhile
  
  
  data = [1, 2, 3, 4]
  
  iter1 = takewhile(lambda x: x &lt; 5, data)
  iter2 = copy(iter1)
  iter3 = deepcopy(iter1)
  
  [i for i in iter1]    #[1, 2, 3, 4]
  [i for i in iter2]    #[] because it's the same iterator
  [i for i in iter3]    #[1, 2, 3, 4]
  </code></pre>
  
  <p>Is this the expected behavior? Nowhere in the documentation did I find any information about copying iterators. I know that there is an itertools.tee() function, but its usability is limited (e.g. when we iterate over a changing collection).</p>