Is there a “do … until” in Python?
Possible Duplicate:
Emulate a do-while loop in Python?
有没有
在Python中,还是实现这种循环结构的好方法?
- 副本:stackoverflow.com/questions/743164/do-while-loop-in-python
- 我对python的最大愿望是"做一段时间"(尽管它应该称为until)。
- 在搜索中没有找到副本,我想是因为它的标题是"DoWhile"
- @伦纳特雷格布罗:我也希望如此,直到!我阅读了mail.python.org/pipermail/python dev/2006年2月/060718.ht‌&8203;ml上的评论。
- 我想指出的是,"做的时候"和"做到"是不同的。
在Python中没有do-while循环。
这是一个类似的结构,取自上面的链接。
1 2 3 4
| while True:
do_something()
if condition():
break |
- 顺便说一句,这叫做"半圈半"。Python继续支持这种构造,因为它是正确编写和理解的最简单的循环模式之一。参见cs.duke.edu/~ola/patterns/plopd/loops.html loop-and-a-half
- @布兰登这和:while !condition do_something()有什么不同吗?
- @bort半循环结构保证至少执行一次do_something(),即使condition()在循环开始时是真的。如果开始时condition()的值为true,则您的while not condition(): do_something()构造将永远不会执行do_something()。
- @布兰登是的,"简单,自然的方式"是一种循环半(tm)的方式,特别是因为[只有一个fscking-]直到方式比"无限循环中断"更难掌握…真正的Python,消化道排泄方式。ps:until不在python中的唯一原因是,它们找不到将其合并到强制缩进语法中的明智方法(至少函数语言用尾部递归来补偿这一点)。
没有预先打包的"do while",但是实现特殊循环结构的一般python方法是通过生成器和其他迭代器,例如:
1 2 3 4 5 6 7
| import itertools
def dowhile(predicate):
it = itertools.repeat(None)
for _ in it:
yield
if not predicate(): break |
例如:
1 2 3 4
| i=7; j=3
for _ in dowhile(lambda: i<j):
print i, j
i+=1; j-=1 |
根据需要执行一条腿,即使谓词在开头已经是假的。
通常,最好将更多的循环逻辑封装到生成器(或其他迭代器)中——例如,如果经常出现一个变量增加、一个变量减少,并且需要进行do/while循环比较的情况,则可以对其进行编码:
1 2 3 4 5
| def incandec(i, j, delta=1):
while True:
yield i, j
if j <= i: break
i+=delta; j-=delta |
你可以这样使用:
1 2
| for i, j in incandec(i=7, j=3):
print i, j |
这取决于您想在生成器(或其他迭代器)中放入多少与循环相关的逻辑,以及您想在生成器之外拥有多少逻辑(就像您可以使用函数、类或其他机制从主执行流中重构代码一样),但一般来说,我喜欢看到EDO中使用的生成器cx1〔0〕循环几乎没有(理想情况下没有)"循环控制逻辑"(与更新下一个循环段的状态变量和/或测试是否应该再次循环相关的代码)。
- 你可以使用itertools.takewhile。
我更喜欢使用循环变量,因为它读起来比"while 1:"好一点,而且没有难看的break语句:
1 2 3 4
| finished = False
while not finished:
... do something...
finished = evaluate_end_condition() |
没有,而是使用一个while循环,例如:
1 2 3 4
| while 1:
...statements...
if cond:
break |
- 为什么是while 1?while True出了什么问题?为什么要强制从int转换为bool?
- @实际上,在python 2.x中,true/false不是关键字,它们只是内置在全局常量中(可以像其他变量一样重新分配),因此解释器必须检查它们指向的内容。见stackoverflow.com/a/3815387/311220
- "翻译必须检查他们指的是什么?"什么?您是否声称这是某种有用的优化?如果是这样,您是否有timeit基准来证实这一主张?
- python 2.7.3$python-mtimeit'while 0:pass'100000000个循环,每循环最好3:0.0132个usec$python-mtimeit'while false:pass'10000000个循环,每循环最好3:0.0538个usec
- @英特德:"我们应该忘记小效率,比如说97%的时间:过早的优化是万恶之源。"—我说,唐纳德·克努斯明显地超过了微不足道的速度。
- @JPMC26我只是在支持0和1比False和True快的说法。对于其他3%的人来说,这有助于了解(也许是反直觉的)1比True更快。
- 我知道,但性能的增长是如此之小,如果这类时间真的很重要,你可以节省很多更好的性能,节省了使用Python的解释性语言的开销,并与C或C++或其他本地的。因此,当这个性能改进实际上是一个好主意时,我无法想到一个用例。
- @JPMC26我在编程竞赛中使用了Python来缩短开发时间。有时,在一个难以移植的解决方案中,一个严格的数字循环是瓶颈,而将"真"转换为"EDOCX1"〔10〕会将我的解决方案从"超过时间限制"转换为"正确",速度会略微提高10%-20%。仅仅因为你从未需要过优化,它就没有它的用途。
- 所有这些都告诉我,我们需要更好的元编程,这样我们就可以把自己的do-while、until等包在一块代码上。不管怎样,我都能梦到。