[Python-ideas] Variations on a loop

Sat Aug 30 19:56:01 CEST 2008

```On 30 Aug 2008, at 16:38, Arnaud Delobelle wrote:

>
> On 29 Aug 2008, at 13:49, Bruce Frederiksen wrote:
>
>> Bruce Leban wrote:
>>>
>>> For example:
>>>
>>>   result = ""
>>>   for x in items:
>>>       result += str(x)
>>>   interstitially:
>>>       result += ", "
>>>   contrariwise:
>>>       result = "no data"
>> We already have statements that only apply within loops (break and
>> continue), how about some expressions that only apply in for loops:
>> 'last' and 'empty':
>>
>> for x in items:
>>  result += str(x)
>>  if not last:
>>      result += ', '
>> else:
>>  if empty:
>>      result = "no data"
>>
>> -bruce (not to be confused with Bruce :-)
>
> note that this can be achieved without 'empty'
>
> for x in items:
>    result += str(x)
>    if last:
>        break
>    else:
>        result += ', '
> else:
>    result = "no data"
>
> Something like this can be implemented in Python with the following
> helper function:
>
> def flaglast(iterable):
>    it = iter(iterable)
>    for prev in it:
>        break
>    else:
>        return
>    for item in it:
>        yield prev, False
>        prev = item
>    yield prev, True
>
> E.g.
>
> >>> list(flaglast([1,2,3]))
> [(1, False), (2, False), (3, True)]
>
> Then you can write your code snippet as:
>
> for x, last in flaglast(items):
>    result += str(x)
>    if last:
>        break
>    else:
>        result += ', '
> else:
>    result = "no data"
>
> --
> Arnaud
>

Also having a 'last' local to a loop implies a lot of overhead in case
one is looping over an iterable whose length is not known - in essence
the overhead in my flaglast function.

Finally, my function works gracefully with nested loops:

for i, i_last in flaglast(items):
for j, j_last in flaglast(jtems):
...

without the need for a 'named loop', about which I feel very
circumspect.

--
Arnaud

```