当前位置:  开发笔记 > 编程语言 > 正文

在Python中模拟do-while循环?

如何解决《在Python中模拟do-while循环?》经验,为你挑选了10个好方法。

我需要在Python程序中模拟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 
    s = i.next()
', 'StopIteration
']

我能做些什么来捕获'stop iteration'异常并正确地打破while循环?

以下将伪代码示为可能需要这样的事物的示例.

状态机:

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

Tom.. 905

我不确定你要做什么.您可以像这样实现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

另请参阅[PEP 315](https://www.python.org/dev/peps/pep-0315/)了解官方立场/理由:"建议使用该语言的用户使用内部的真实形式if-break当do-while循环是合适的." (33认同)

令人遗憾的是python没有do-while循环.Python干了,嗯? (3认同)


小智.. 290

这是一个模拟do-while循环的非常简单的方法:

condition = True
while condition:
    # loop body here
    condition = test_loop_condition()
# end of loop

do-while循环的关键特性是循环体总是至少执行一次,并且在循环体的底部评估条件.这里显示的控制结构完成了这两个,不需要异常或break语句.它确实引入了一个额外的布尔变量.



1> Tom..:

我不确定你要做什么.您可以像这样实现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


另请参阅[PEP 315](https://www.python.org/dev/peps/pep-0315/)了解官方立场/理由:"建议使用该语言的用户使用内部的真实形式if-break当do-while循环是合适的."
令人遗憾的是python没有do-while循环.Python干了,嗯?

2> 小智..:

这是一个模拟do-while循环的非常简单的方法:

condition = True
while condition:
    # loop body here
    condition = test_loop_condition()
# end of loop

do-while循环的关键特性是循环体总是至少执行一次,并且在循环体的底部评估条件.这里显示的控制结构完成了这两个,不需要异常或break语句.它确实引入了一个额外的布尔变量.


我最喜欢这个解决方案的原因是它没有添加另一个条件,它仍然只是一个循环,如果你为辅助变量选择一个好名字,整个结构就很清楚了.
它并不总是添加额外的布尔变量.通常存在已经存在的状态可以被测试的东西.
@ToolmakerSteve我不同意.我很少在循环中使用`break`,当我在代码中遇到它时,我发现循环通常可以在没有它的情况下编写.提出的解决方案是,IMO,*在python中表示do while构造的最清晰的方法.
注意:虽然这确实解决了原始问题,但这种方法不如使用"break"灵活.具体来说,如果在`test_loop_condition()`之后需要逻辑,那么一旦完成就不应该执行它,它必须包含在`if condition:`中.顺便说一下,"条件"是模糊的.更具描述性:`more`或`notDone`.

3> evan54..:

我下面的代码可能是一个有用的实施,强调的主要区别DO-而 VS 而据我所知.

所以在这种情况下,你总是至少经历一次循环.

first_pass = True
while first_pass or condition:
    first_pass = False
    do_stuff()


我认为,正确的答案是正确的.另外,它可以避免**break**,以便在try/except块中安全使用.

4> vartec..:

异常将打破循环,因此您可以在循环外处理它.

try:
  while True:
    if s:
      print s
    s = i.next()
except StopIteration:   
  pass

我猜你的代码的问题是没有定义break内部行为except.通常break只有一个级别,所以例如break内部try直接进入finally(如果存在)一个try,但不是循环.

相关PEP:http
://www.python.org/dev/peps/pep-3136相关问题:突破嵌套循环


虽然只在try语句中包含您希望抛出异常的内容,但这样做是很好的做法,以免捕获不必要的异常.
@PiPeep:RTFM,搜索EAFP.
在try/except/finally语句的任何子句中,break和continue都是完美定义的.他们只是忽略它们,然后根据需要突破或继续进行包含while或for循环的下一次迭代.作为循环结构的组件,它们仅与while和for语句相关,如果它们在到达最内层循环之前遇到类或def语句,则会触发语法错误.他们忽略if,with和try语句.
@PiPeep:没问题,请记住,某些语言的真实情况可能不适用于其他语言.Python针对异常的密集使用进行了优化.

5> 小智..:
do {
  stuff()
} while (condition())

- >

while True:
  stuff()
  if not condition():
    break

你可以做一个功能:

def do_while(stuff, condition):
  while condition(stuff()):
    pass

但是1)这很难看.2)条件应该是一个带有一个参数的函数,应该由stuff填充(这是使用经典while循环的唯一原因.)


写`while True:stuff(); 如果不是条件():break`是一个非常好的主意.谢谢!
@ZeD,为什么是1)丑陋?很好,恕我直言

6> u0b34a0f6ae..:

这是一个不同模式的疯狂解决方案 - 使用协同程序.代码仍然非常相似,但有一个重要区别; 根本没有退出条件!当您停止向数据提供数据时,协程(协程链确实)就会停止.

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().


你今天如何在Python 3.x中写这个?

7> 小智..:

我这样做的方式如下......

condition = True
while condition:
     do_stuff()
     condition = ()

在我看来这是一个简单的解决方案,我很惊讶我已经没有在这里看到它.这显然也可以反过来

while not condition:

等等



8> Mark..:

对于包含try语句的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()

或者,当不需要'finally'条款时

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



9> MuSheng..:
while condition is True: 
  stuff()
else:
  stuff()


所有需要的是`while condition:`因为`是True`是隐含的.
EW.这似乎比使用休息时更加丑陋.
这很聪明,但它需要`stuff`作为函数或代码体重复.
不一样的逻辑,因为在条件的最后一次迭代!= True:它最后一次调用代码.作为***Do While***,首先调用代码,然后在重新运行之前检查条件.Do While:**执行块一次; 然后检查并重新运行**,这个答案:**检查并重新运行; 然后执行一次代码块**.很大的区别!

10> Naftuli Kay..:

快速破解:

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

推荐阅读
手机用户2402852387
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有