Take the tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

Take the following example:

>>> for item in [i * 2 for i in range(1, 10)]:
    print item


2
4
6
8
10
12
14
16
18

Is [i * 2 for i in range(1, 10)] computed every time through the loop, or just once and stored? (Also, what is the proper name for that part of the expression?)

One reason I would want to do this is that I only want the results of that list comprehension to be available in the loop.

share|improve this question
add comment

3 Answers

up vote 5 down vote accepted

A good translation of for i in <whatever>: <loopbody>, showing exactly what it does for any <whatever> and any <loopbody>:

_aux = iter(<whatever>)
while True:
  try: i = next(_aux)
  except StopIteration: break
  <loopbody>

except that the pseudo-variable I have here named _aux actually remains unnamed.

So, <whatever> always gets evaluated just once (to get an iter() from it) and the resulting iterator is nexted until it runs out (unless there's some break in the <loopbody>).

With a listcomp, as you've used, the evaluation produces a list object (which in your code sample remains unnamed). In the very similar code:

for item in (i * 2 for i in range(1, 10)): ...

using a genexp rather than the listcomp (syntactically, round parentheses instead of the listcomp's square brackets), it's the next() that actually does most of the work (advancing i and doubling it), instead of lumping all work at construction time -- this takes up less temporary memory, and may save time if the loop body's reasonably likely to break out early, but except in such special conditions (very tight memory or likely early loop termination) a listcomp may typically be (by a wee little bit) faster.

share|improve this answer
add comment

In that case, you are constructing a list in memory and then you are iterating over the contents of the list, so yes, it is computed once and stored. it is the no different than doing

i for i in [2,4,6,8]:
   print(i)

If you do iter(i * 2 for i in xrange(1,10)), you get an iterator which evaluates on each iteration.

share|improve this answer
add comment

All members of the expression list are calculated once, and then iterated over.

In Python 2.x, the variable used in a LC does leak out into the parent scope, but since the LC has already been evaluated, the only value available is the one used to generate the final element in the resultant list.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.
{"cc_re__cc_re__cc_by_sa_3_0": ["        <li><a href=\"http://area51.stackexchange.com\" title=\"proposing new sites in the Stack Exchange network\">Area 51</a></li>\r\n                        <li><a href=\"http://careers.stackoverflow.com\">Stack Overflow Careers</a></li>\r\n                    \r\n                </ol>\r\n            </td>\r\n    </tr>\r\n</table>\r\n                </div>\r\n            </div>\r\n\r\n            <div id=\"copyright\">\r\n                site design / logo &#169; 2013 stack exchange inc; user contributions licensed under <a href=\"http://creativecommons.org/licenses/by-sa/3.0/\" rel=\"license\">cc-wiki</a> \r\n with <a href=\"http://blog.stackoverflow.com/2009/06/attribution-required/\" rel=\"license\">attribution required</a>\r\n            </div>\r\n            <div id=\"footer-flair\">\r\n                <a href=\"http://creativecommons.org/licenses/by-sa/3.0/\" class=\"cc-wiki-link\"></a>\r\n            </div>\r\n            <div id=\"svnrev\">\r\n                rev 2013.12.13.1225\r\n            </div>\r\n            \r\n        </div>\r\n    </div>\r\n    <noscript>\r\n        <div id=\"noscript-warning\">Stack Overfl", "ol>\r\n            </td>\r\n    </tr>\r\n</table>\r\n                </div>\r\n            </div>\r\n\r\n            <div id=\"copyright\">\r\n                site design / logo &#169; 2013 stack exchange inc; user contributions licensed under <a href=\"http://creativecommons.org/licenses/by-sa/3.0/\" rel=\"license\">cc-wiki</a> \r\n with <a href=\"http://blog.stackoverflow.com/2009/06/attribution-required/\" rel=\"license\">attribution required</a>\r\n            </div>\r\n            <div id=\"footer-flair\">\r\n                <a href=\"http://creativecommons.org/licenses/by-sa/3.0/\" class=\"cc-wiki-link\"></a>\r\n            </div>\r\n            <div id=\"svnrev\">\r\n                rev 2013.12.13.1225\r\n            </div>\r\n            \r\n        </div>\r\n    </div>\r\n    <noscript>\r\n        <div id=\"noscript-warning\">Stack Overflow works best with JavaScript enabled<img src=\"http://pixel.quantserve.com/pixel/p-c1rF4kxgLUzNc.gif\" alt=\"\" class=\"dno\"></div>\r\n    </noscript>\r\n\r\n    <script type=\"text/javascript\">var _gaq=_gaq||[];_gaq.push(['_setAccount','UA-5620270-1']);\r\n        _gaq.push(['_setCustomVar', "], "copyright__copyright__copyright": ["ist are calculated once, and then iterated over.\n\nIn Python 2.x, the variable used in a LC does leak out into the parent scope, but since the LC has already been evaluated, the only value available is the one used to generate the final element in the resultant list.\n\nshare|improve this answer\nadd comment\n\nYour Answer\n\n\u00a0\ndiscard\n\nBy posting your answer, you agree to the privacy policy and terms of service.\n\nNot the answer you're looking for? Browse other questions tagged or ask your own question."]}