i=2; lst=[i**=2 while i<1000]

Duncan Booth duncan.booth at invalid.invalid
Tue Dec 6 10:17:18 EST 2005


Daniel Schüle wrote:

> hi,
> 
> [...]
> 
>>># pseudo code
>>>i=2
>>>lst=[i**=2 while i<1000]
>>>
>>>of course this could be easily rewritten into
>>>i=2
>>>lst=[]
>>>while i<1000:
>>>     i**=2
>>>     lst.append(i)
>>>
>> 
>> 
>> Neither of these loops would terminate until memory is exhausted. Do
>> you have a use case for a 'while' in a list comprehension which would
>> terminate?
> 
> unless I am missing something obvious, I can not see why the loop
> should not terminate
> sure pseudo code is not executable but the other one works
> while tests the boolean expression first then decides whether to
> execute the body or not, in particular no next-iterator is
> involved(??) as it would be in
> lst=range(5)
> for i in lst:
>      del lst[0]
> 
Yes, I wasn't paying attention. The pseudo-code fails because you would 
need to support assignment and generating a value inside the loop, but the 
simple loop does work.

The simple case in the pseudo-coded loop isn't nearly general enough, what 
if you wanted a tuple, or i**2+1 as each loop value. You would need syntax 
which generate more complex list values e.g:

lst = [ (i, i**2) while i < 1000; i**=2 ]

One current way to write this would be:

def squaring(start, end):
  i = start
  while i < end:
      yield i
      i = i**2

Then you can do:

   lst = [(i, i**2) for i in squaring(1, 1000) ]

which has the advantage of pulling all the complex logic out of the list 
comprehension.



More information about the Python-list mailing list