Problem
In a Python program, I need to simulate a do-while loop. Unfortunately, the following simple code does not function:
list_of_ints = [ 1, 2, 3 ]
iterator = list_of_ints.__iter__()
element = None
while True:
if element:
print element
try:
element = iterator.next()
except StopIteration:
break
print "done"
It outputs the following output instead of “1,2,3,done”:
[stdout:]1
[stdout:]2
[stdout:]3
None['Traceback (most recent call last):
', ' File "test_python.py", line 8, in <module>
s = i.next()
', 'StopIteration
']
What can I do to intercept the’stop iteration’ exception and appropriately break the while loop?
As pseudocode, an illustration of why such a thing could be required is presented below.
State machine:
s = ""
while True :
if state is STATE_CODE :
if "//" in s :
tokens.add( TOKEN_COMMENT, s.split( "//" )[1] )
state = STATE_COMMENT
else :
tokens.add( TOKEN_CODE, s )
if state is STATE_COMMENT :
if "//" in s :
tokens.append( TOKEN_COMMENT, s.split( "//" )[1] )
else
state = STATE_CODE
# Re-evaluate same line
continue
try :
s = i.next()
except StopIteration :
break
Asked by grigoryvp
Solution #1
I’m not sure what you’re attempting. A do-while loop can be implemented as follows:
while True:
stuff()
if fail_condition:
break
Or:
stuff()
while not fail_condition:
stuff()
What are you doing trying to use a do while loop to print the stuff in the list? Why not simply use:
for i in l:
print i
print "done"
Update:
So, do you have a line-by-line list? And you want to keep going over it again and again? How about this:
for s in l:
while True:
stuff()
# use a "break" instead of s = i.next()
Is that something that comes close to what you’re looking for? It would be as follows, using your code as an example:
for s in some_list:
while True:
if state is STATE_CODE:
if "//" in s:
tokens.add( TOKEN_COMMENT, s.split( "//" )[1] )
state = STATE_COMMENT
else :
tokens.add( TOKEN_CODE, s )
if state is STATE_COMMENT:
if "//" in s:
tokens.append( TOKEN_COMMENT, s.split( "//" )[1] )
break # get next s
else:
state = STATE_CODE
# re-evaluate same line
# continues automatically
Answered by Tom
Solution #2
Here’s a quick and dirty approach to make a do-while loop:
condition = True
while condition:
# loop body here
condition = test_loop_condition()
# end of loop
A do-while loop has two main characteristics: the loop body always executes at least once, and the condition is assessed at the bottom of the loop body. Without the use of exceptions or break statements, the control structure shown below achieves both of these goals. It does, however, add one more Boolean variable.
Answered by powderflask
Solution #3
My code below may be useful in demonstrating the primary difference between do-while and while, as far as I can see.
So, in this scenario, you must complete the loop at least once.
first_pass = True
while first_pass or condition:
first_pass = False
do_stuff()
Answered by evan54
Solution #4
do {
stuff()
} while (condition())
->
while True:
stuff()
if not condition():
break
You can perform the following function:
def do_while(stuff, condition):
while condition(stuff()):
pass
However, 1) it is unsightly. 2) The condition should be a one-parameter function that is designed to be populated with data (this is the sole reason not to use the conventional while loop).
Answered by ZeD
Solution #5
Because an exception will break the loop, you should handle it outside of it.
try:
while True:
if s:
print s
s = i.next()
except StopIteration:
pass
The issue with your code, I believe, is that the behavior of break inside except is not defined. Break usually just travels one level up, thus break inside try, for example, goes straight to finally (if one exists) an out of the try, but not out of the loop.
http://www.python.org/dev/peps/pep-3136 is a related PEP. Breaking out of nested loops is a similar question.
Answered by vartec
Post is based on https://stackoverflow.com/questions/743164/how-to-emulate-a-do-while-loop