Why can generator expressions be iterated over only once?
<p>This program:</p>

<pre><code>def pp(seq):
    print(''.join(str(x) for x in seq))
    print(''.join(str(x) for x in seq))
    print('---')

pp([0,1,2,3])
pp(range(4))  # range in Python3, xrange in Python2
pp(x for x in [0,1,2,3])
</code></pre>

<p>prints this:</p>

<pre><code>0123
0123
---
0123
0123
---
0123

---
</code></pre>

<p>It is a result of the difference between <code>container.__iter__</code> and <code>iterator.__iter__</code>. Both are documented here: <a href="https://docs.python.org/3/library/stdtypes.html#typeiter" rel="nofollow">https://docs.python.org/3/library/stdtypes.html#typeiter</a>. If the <code>__iter__</code> returns a new iterator each time, we see two repeating lines. And if it returns the same iterator each time, we see just one line, beacuse the iterator is exhausted after that.</p>

<p>My question is <strong>why it was decided to implement generator expressions not similar to other objects that seem to be equivalent or at least very similar?</strong></p>

<p>Here is another example that generator expressions are different than other similar types which may lead to unexpected outcome.</p>

<pre><code>def pp(seq):
    # accept only non-empty sequences
    if seq:
        print("data ok")
    else:
        print("required data missing")

pp([])
pp(range(0))
pp(x for x in []) 
</code></pre>

<p>output:</p>

<pre><code>required data missing
required data missing
data ok
</code></pre>

<blockquote>
  <p>My question is why it was decided to implement generator expressions not similar to other objects that seem to be equivalent or at least very similar?</p>
</blockquote>

<p>Because that's exactly what a generator is, if you make it similar to other iterables you have to preserve all the items in memory and then what you have is not a generator any more.</p>

<p>The main benefit of using generators is that they doesn't consume the memory and just generate the items on demand, and this makes them to be one shot iterables, because otherwise if you want to be able to iterate over them multiple times you have to preserve them in memory. </p>

python