I think you&#x27;re referring to:<p><pre><code>  for i in range(large_number):
     ...
</code></pre>
(similarly enumerate, zip etc)<p>i.e., where you don&#x27;t bind the generator to a variable, but instead immediately consume <i>and</i> reading from it as an iterator has no other side-effects.<p>And that&#x27;s the only usage of generators that in my usage is both common and practical.
Other use has always quickly become a mess for the above named reasons.<p>I don&#x27;t disagree generators can be occasionally useful (or often, for your special applications). But mostly it&#x27;s a pain that they are the only thing many APIs return and that they are not visually distinctive (in usage) from lists and iterators. For example<p><pre><code>  c = sqlite3.connect(path)
  rows = c.execute(&#x27;select blablabla&#x27;)
  do_some_calculation(rows)
  print_table(rows)
</code></pre>
Gotcha! &quot;rows&quot; was <i>probably</i> already empty when print_table was supposed to print it.
But how can you know? Hunt down all the code, see what the functions do and what they want to receive (lists, iterators, generators? probably they don&#x27;t even know). And what if the functions change later? Even subtler bugs occur if the input is consumed only partly.<p>So by far the common (= no billions of rows) sane thing to do is<p><pre><code>  rows = list(c.execute(&#x27;select blablabla&#x27;))
</code></pre>
Which is arguably annoying and requires a wrapper for non-trivial things.