1073 Stimmen

Wie emuliert man eine do-while-Schleife?

Ich muss eine do-while-Schleife in einem Python-Programm emulieren. Leider funktioniert der folgende unkomplizierte Code nicht:

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"

Anstelle von "1,2,3,done" wird die folgende Ausgabe gedruckt:

[stdout:]1
[stdout:]2
[stdout:]3
None['Traceback (most recent call last):
', '  File "test_python.py", line 8, in <module>
    s = i.next()
', 'StopIteration
']

Was kann ich tun, um die Ausnahme "Stop Iteration" abzufangen und eine while Schleife richtig zu unterbrechen?

Ein Beispiel dafür, warum so etwas notwendig sein kann, ist unten als Pseudocode dargestellt.

Zustandsmaschine:

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

18voto

Ich glaube, dass diese do-while-Simulation auf Python ein Syntaxformat hat, das dem do-while-Strukturformat in C und Java am nächsten kommt.

do = True
while do:
    [...]
    do = <condition>

17voto

u0b34a0f6ae Punkte 45029

Hier ist eine verrücktere Lösung nach einem anderen Muster - unter Verwendung von Coroutines. Der Code ist immer noch sehr ähnlich, aber mit einem wichtigen Unterschied: Es gibt überhaupt keine Ausstiegsbedingungen! Die Coroutine (eigentlich eine Kette von Coroutines) hört einfach auf, wenn Sie sie nicht mehr mit Daten füttern.

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)

Der obige Code sammelt alle Token als Tupel in tokens und ich nehme an, es gibt keinen Unterschied zwischen .append() y .add() im ursprünglichen Code.

17voto

Gareth Lock Punkte 209

Ich habe das folgendermaßen gemacht...

condition = True
while condition:
     do_stuff()
     condition = (<something that evaluates to True or False>)

Das scheint mir die einfachste Lösung zu sein, und ich bin überrascht, dass ich sie hier noch nicht gesehen habe. Dies kann natürlich auch invertiert werden zu

while not condition:

usw.

10voto

Jonathan Shemer Punkte 229

Python 3.8 hat die Antwort.

Das nennt man Zuweisungsausdrücke. aus dem Dokumentation :

# Loop over fixed length blocks
while (block := f.read(256)) != '':
    process(block)

8voto

nehem Punkte 10704

While-Schleife:

while condition:
  logic

Do while-Schleife:

while True:
  logic
  if not condition:
    break

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X