파이썬에서 do-while 루프를 모방 하시겠습니까?
-
09-09-2019 - |
문제
파이썬 프로그램에서 DO-While 루프를 모방해야합니다. 불행히도 다음 간단한 코드는 작동하지 않습니다.
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"
"1,2,3, 완료"대신 다음 출력을 인쇄합니다.
[stdout:]1
[stdout:]2
[stdout:]3
None['Traceback (most recent call last):
', ' File "test_python.py", line 8, in <module>
s = i.next()
', 'StopIteration
']
'반복 중지'예외를 잡고 제대로 루프를 깨뜨리려면 어떻게해야합니까?
그러한 것이 필요한 이유의 예는 아래에 의사 코드로 표시됩니다.
상태 머신:
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
해결책
나는 당신이 무엇을하려고하는지 잘 모르겠습니다. 다음과 같은 DO-WHILE 루프를 구현할 수 있습니다.
while True:
stuff()
if fail_condition:
break
또는:
stuff()
while not fail_condition:
stuff()
목록에있는 물건을 인쇄하기 위해 Do while 루프를 사용하려고하는 일은 무엇입니까? 왜 사용하지 않는가 :
for i in l:
print i
print "done"
업데이트:
그래서 당신은 줄 목록이 있습니까? 그리고 당신은 그것을 계속 반복하고 싶습니까? 어때요 :
for s in l:
while True:
stuff()
# use a "break" instead of s = i.next()
그것은 당신이 원하는 것과 가까운 것처럼 보입니까? 코드 예제를 사용하면 다음과 같습니다.
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
다른 팁
다음은 Do-While 루프를 모방하는 매우 간단한 방법입니다.
condition = True
while condition:
# loop body here
condition = test_loop_condition()
# end of loop
Do-While 루프의 주요 특징은 루프 본체가 항상 한 번 이상 실행되며 루프 본체의 바닥에서 조건이 평가된다는 것입니다. 여기서 제어 구조는 예외 나 브레이크 명령문이 필요하지 않고이 두 가지를 달성합니다. 하나의 추가 부울 변수를 소개합니다.
예외는 루프를 깨뜨 리므로 루프 외부에서 처리 할 수도 있습니다.
try:
while True:
if s:
print s
s = i.next()
except StopIteration:
pass
코드의 문제는 그 행동이라고 생각합니다. break
내부에 except
정의되지 않았습니다. 일반적으로 break
한 레벨 만 올라갑니다 break
내부에 try
직접갑니다 finally
(존재하는 경우) AN에서 try
, 그러나 루프에서 벗어나지는 않습니다.
관련 PEP : http://www.python.org/dev/peps/pep-3136
관련 질문 : 중첩 된 루프에서 분해
do {
stuff()
} while (condition())
->
while True:
stuff()
if not condition():
break
기능을 수행 할 수 있습니다.
def do_while(stuff, condition):
while condition(stuff()):
pass
그러나 1) 못 생겼다. 2) 조건은 하나의 매개 변수가있는 함수 여야하며, 물건으로 채워야한다고 가정합니다 (유일한 이유입니다. ~ 아니다 클래식 While 루프를 사용하려면)
다음은 코 루틴을 사용하는 다른 패턴의 더 미친 솔루션입니다. 코드는 여전히 매우 유사하지만 한 가지 중요한 차이점이 있습니다. 출구 조건이 전혀 없습니다! 코 루틴 (Coroutines의 체인)은 데이터를 사용하여 공급을 중단 할 때 멈 춥니 다.
def coroutine(func):
"""Coroutine decorator
Coroutines must be started, advanced to their first "yield" point,
and this decorator does this automatically.
"""
def startcr(*ar, **kw):
cr = func(*ar, **kw)
cr.next()
return cr
return startcr
@coroutine
def collector(storage):
"""Act as "sink" and collect all sent in @storage"""
while True:
storage.append((yield))
@coroutine
def state_machine(sink):
""" .send() new parts to be tokenized by the state machine,
tokens are passed on to @sink
"""
s = ""
state = STATE_CODE
while True:
if state is STATE_CODE :
if "//" in s :
sink.send((TOKEN_COMMENT, s.split( "//" )[1] ))
state = STATE_COMMENT
else :
sink.send(( TOKEN_CODE, s ))
if state is STATE_COMMENT :
if "//" in s :
sink.send(( TOKEN_COMMENT, s.split( "//" )[1] ))
else
state = STATE_CODE
# re-evaluate same line
continue
s = (yield)
tokens = []
sm = state_machine(collector(tokens))
for piece in i:
sm.send(piece)
위의 코드는 모든 토큰을 튜플로 수집합니다 tokens
그리고 나는 그 사이에 차이가 없다고 생각합니다 .append()
그리고 .add()
원래 코드에서.
내가이 작업을 수행 한 방식은 다음과 같습니다.
condition = True
while condition:
do_stuff()
condition = (<something that evaluates to True or False>)
이것은 나에게 단순한 솔루션 인 것 같습니다. 나는 이미 여기서 보지 못한 것에 놀랐습니다. 이것은 분명히 반전 될 수 있습니다
while not condition:
등.
Do-- while 루프가 포함 된 시도 문
loop = True
while loop:
generic_stuff()
try:
questionable_stuff()
# to break from successful completion
# loop = False
except:
optional_stuff()
# to break from unsuccessful completion -
# the case referenced in the OP's question
loop = False
finally:
more_generic_stuff()
또는 '마지막으로'조항이 필요하지 않은 경우
while True:
generic_stuff()
try:
questionable_stuff()
# to break from successful completion
# break
except:
optional_stuff()
# to break from unsuccessful completion -
# the case referenced in the OP's question
break
while condition is True:
stuff()
else:
stuff()
빠른 해킹 :
def dowhile(func = None, condition = None):
if not func or not condition:
return
else:
func()
while condition():
func()
그렇게 사용하십시오 :
>>> x = 10
>>> def f():
... global x
... x = x - 1
>>> def c():
global x
return x > 0
>>> dowhile(f, c)
>>> print x
0
그냥하지 그래
for s in l :
print s
print "done"
?
이것이 도움이되는지 확인하십시오.
예외 핸들러 안에 플래그를 설정하고 S에서 작업하기 전에 확인하십시오.
flagBreak = false;
while True :
if flagBreak : break
if s :
print s
try :
s = i.next()
except StopIteration :
flagBreak = true
print "done"
리소스가 탈출 할 수없는 상태에서 반복되는 시나리오에 있거나 예외를 던지는 비슷한 것들이 있다면 다음과 같은 것을 사용할 수 있습니다.
import time
while True:
try:
f = open('some/path', 'r')
except IOError:
print('File could not be read. Retrying in 5 seconds')
time.sleep(5)
else:
break