[Python-ideas] for-while statement
Andrew Barnert
abarnert at yahoo.com
Wed Feb 19 22:02:33 CET 2014
On Feb 19, 2014, at 5:34, Alejandro López Correa <alc at spika.net> wrote:
> Hello,
>
> I think adding an optional "WHILE" clause in "FOR" loops might be
> useful sometimes (shorter code and/or improved readability):
>
> for #VAR# in #SEQUENCE# while #WATCHDOG_EXPRESSION#:
> #CODE_BLOCK#
>
> Examples:
>
> keepRunning = True
> for i in range(100) while keepRunning:
> keepRunning = do_some_work( i )
>
> found = False
> for candidate in sequence while not found:
> try:
> process( candidate )
> found = True
> except InvalidCandidate:
> pass
>
> retryCount = 7
> for i in range(1,1+retryCount) while resource.acquire() == FAIL:
> sleep( i**2 )
>
>
> At the moment, I usually implement this either with ugly breaks:
>
>
> for i in range(100):
> if not do_some_work( i ):
> break
The only reason you think they're "ugly" is that you're thinking in C terms, not Python terms.
This version is shorter, it's more explicit, and it has fewer places for you or after code maintainer to screw up and create bugs. (And yes, even in a trivial case like this, I've seen people write keepRunnig = ...)
And this becomes even more apparent in the longer cases. You're relying on the fact that setting a flag _plus_ falling off the end of a loop (which isn't nearly as obvious or visible or explicit) equals break.
>
> found = False
> for candidate in sequence:
> try:
> process_candidate()
> except InvalidCandidate:
> pass
> else:
> found = True
> break
Here, you don't need found at all. I suspect you're not using for...else because C doesn't have it?
>
>
> Or with while loops and counters (or counting-like expressions):
>
>
> i = 1
> while i <= retryCount and not resource.acquired:
> if resource.acquire() == FAIL:
> sleep( i**2 )
> i += 1
>
>
> Of course, actual code tends to be more complex, with "keepRunning"
> being modified in some branches of "IF" blocks, and there might be
> nested loops where the exit condition for the outer one is set in the
> inner loop. Compare these two examples:
>
> found = False
> for filePath in glob( '*.data' ):
> for line in open( filePath, 'rt' ):
> if line.startswith( '#' ):
> continue
> if handle( line ):
> found = True
> break
> if found:
> break
>
> found = False
> for filePath in glob( '*.data' ) while not found:
> for line in open( filePath, 'rt' ) while not found:
> if line.startswith( '#' ):
> continue
> if handle( line ):
> found = True
>
> -- Alejandro
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
More information about the Python-ideas
mailing list