【问题标题】:Is there a "do ... until" in Python? [duplicate]Python中是否有“做...直到”? [复制]
【发布时间】:2020-02-02 21:32:12
【问题描述】:

有没有

do until x:
    ...

在 Python 中,还是实现这种循环结构的好方法?

  • 一个do-while(虽然它应该被称为until)是我对Python的最大愿望。
  • 重复没有出现在搜索中,我想是因为它的标题是“do-while”
  • @LennartRegebro:我也希望如此,直到(!)我阅读了mail.python.org/pipermail/python-dev/2006-February/060718.html 上的评论。
  • 我想指出,\"do while\" 与 \"do until\" 不同。

标签: python loops


【解决方案1】:

There is no do-while loop in Python.

这是一个类似的结构,取自上面的链接。

 while True:
     do_something()
     if condition():
        break

【讨论】:

  • 顺便说一句,这被称为“循环半”。 Python 继续支持这种结构,因为它是最容易正确编写和理解的循环模式之一。见cs.duke.edu/~ola/patterns/plopd/loops.html#loop-and-a-half
  • @Brandon 这与:while !condition do_something() 有什么不同吗?
  • @Bort 循环半结构保证do_something() 将至少执行一次,即使condition() 在循环开始时为真。如果 condition() 在开始时评估为 true,您的 while not condition(): do_something() 构造将永远不会执行 do_something()
  • @brandon是的,“简单,自然的方式”是循环半(TM)方式,特别是因为[just-one-fscking-]until方式比“无限循环中断”更难掌握“……真正的 Pythonic,PEP 排泄方式。 PS:直到不在 Python 中的唯一原因是因为他们找不到将其合并到强制缩进语法中的合理方法(至少函数式语言通过尾递归来弥补这一点)。
  • 我会倾向于@Bort 的目标,如果你想保证第一次运行,那么在 while 循环之前do_something()。它不是 DRY,但我认为它最易读。 do_something() while condition do_something()。 @Brandon 发布的文章将其称为sentinel loop。归根结底,这是一个留给 linter、代码库一致性和/或团队选择的风格选择。每次我看到while True 时,我都担心它永远不会结束,这就是为什么我喜欢看到用 while 行设置的条件,即使它不是 DRY;我不想寻找休息或消化疯狂的逻辑树
【解决方案2】:

我更喜欢使用循环变量,因为它读起来比“while 1:”要好一些,而且没有难看的break 语句:

finished = False
while not finished:
    ... do something...
    finished = evaluate_end_condition()

【讨论】:

  • 我也喜欢这个,因为它比其他一些替代品更具可读性
【解决方案3】:

没有预先打包的“do-while”,但实现特殊循环结构的一般 Python 方法是通过生成器和其他迭代器,例如:

import itertools

def dowhile(predicate):
  it = itertools.repeat(None)
  for _ in it:
    yield
    if not predicate(): break

所以,例如:

i=7; j=3
for _ in dowhile(lambda: i<j):
  print i, j
  i+=1; j-=1

根据需要执行一条腿,即使谓词在开始时已经为假。

通常最好将更多循环逻辑封装到您的生成器(或其他迭代器)中——例如,如果您经常遇到一个变量增加、一个变量减少的情况,并且您需要一个 do/while 循环比较它们,您可以编写代码:

def incandec(i, j, delta=1):
  while True:
    yield i, j
    if j <= i: break
    i+=delta; j-=delta

你可以像这样使用:

for i, j in incandec(i=7, j=3):
  print i, j

取决于您要在生成器(或其他迭代器)中放入多少与循环相关的逻辑,以及您想要在它之外拥有多少(就像您可以对函数、类或其他机制的任何其他使用一样)用于从您的主要执行流中重构代码),但一般来说,我喜欢看到在for 循环中使用的生成器几乎没有(理想情况下没有)“循环控制逻辑”(与更新状态变量相关的代码为下一个循环腿和/或测试你是否应该再次循环)。

【讨论】:

  • 你可以使用itertools.takewhile
  • 请注意,takewhile 还会消耗序列/生成器中不满足谓词函数的第一个元素 - 这就是它知道停止获取的方式。但是,如果您想遍历其余部分,认为“现在我将得到谓词为 False 的所有内容”,您将错过其中的第一项。
【解决方案4】:

不,没有。而是使用 while 循环,例如:

while 1:
 ...statements...
  if cond:
    break

【讨论】:

  • 为什么while 1while True 有什么问题?为什么要强制从 int 转换为 bool?
  • @S.Lott,实际上,在 Python 2.X 中,True/False 不是关键字,它们只是内置在全局常量中(可以像任何其他变量一样重新分配),因此解释器必须检查它们指向的内容。见stackoverflow.com/a/3815387/311220
  • Python 2.7.3 $ python -mtimeit 'while 0:pass' 100000000 次循环,最佳 3:每个循环 0.0132 usec $ python -mtimeit 'while False:pass' 10000000 次循环,最佳 3:每个循环 0.0538 usec
  • @jpmc26 我只是支持 01FalseTrue 快的说法。对于另外 3% 的用户,知道(可能违反直觉)1True 快是有帮助的。
  • @jpmc26 我使用 Python 进行编程竞赛以减少开发时间。有时,在难以移植的解决方案中,紧密的数值循环是瓶颈,将“True”切换为1 会使我的解决方案从“超出时间限制”变为“正确”,大约 10%-20%速度增加。仅仅因为您从来不需要优化,它就没有它的用​​途。
猜你喜欢
  • 2010-12-12
  • 2011-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-04
  • 2017-11-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多