在C语言中,我会这样做:
int i;
for (i = 0;; i++)
if (thereIsAReasonToBreak(i))
break;
如何在Python中实现类似的功能?
在C语言中,我会这样做:
int i;
for (i = 0;; i++)
if (thereIsAReasonToBreak(i))
break;
如何在Python中实现类似的功能?
range
”,所以您可以避免while True: i += 1
Answers:
import itertools
for i in itertools.count(start=1):
if there_is_a_reason_to_break(i):
break
在Python 2,range()
并xrange()
仅限于sys.maxsize
。在Python 3中range()
可以更高,尽管不能达到无穷大:
import sys
for i in range(sys.maxsize**10): # you could go even higher if you really want
if there_is_a_reason_to_break(i):
break
因此,最好使用count()
。
takewhile
:for x in takewhile(thereIsAReasonToContinue, count()):
for i in range(sys.maxint)
分隔MemoryError
。您还提到了xrange()
哪个有效。
range
替换了Python2的xrange
。在Python2中,range
创建并返回一个实际的int列表。您将没有足够的内存来容纳这么大的列表
重申thg435的评论:
from itertools import takewhile, count
def thereIsAReasonToContinue(i):
return not thereIsAReasonToBreak(i)
for i in takewhile(thereIsAReasonToContinue, count()):
pass # or something else
或更简洁地说:
from itertools import takewhile, count
for i in takewhile(lambda x : not thereIsAReasonToBreak(x), count()):
pass # or something else
takewhile
模仿“行为良好”的C for循环:您有一个延续条件,但有一个生成器而不是一个任意表达式。您可以在C for循环中执行“行为不佳”的事情,例如i
在循环主体中进行修改。takewhile
如果生成器是某个局部变量的闭包i
,那么您也可以使用来模仿它们。从某种意义上说,定义闭包可以使您特别明显地发现您正在做的事情可能会使您的控制结构混乱。
def infinity():
i=0
while True:
i+=1
yield i
for i in infinity():
if there_is_a_reason_to_break(i):
break
yield
除了懒惰序列生成器之外,我没有其他功能,但是最近一个朋友使用它来提供pushd/popd
函数,而不必维护显式堆栈。非常聪明。
如果您在C语言中执行此操作,那么您的判断就会像在Python中一样模糊:-)
对于在每次迭代开始时通过简单条件检查退出的循环,仅在循环结构本身中执行此操作(在我看来更清楚)。换句话说,就像(如果您需要i
在循环结束之后):
int i = 0;
while (! thereIsAReasonToBreak(i)) {
// do something
i++;
}
或(如果i
可以限制为仅循环):
for (int i = 0; ! thereIsAReasonToBreak(i); ++i) {
// do something
}
那将转化为等效的Python:
i = 0
while not there_is_a_reason_to_break(i):
# do something
i += 1
只有当您需要在循环中间的某个位置退出(或者您的条件足够复杂以至于使循环语句的可读性大大降低)时,您才需要担心中断。
如果您的潜在退出在循环开始时只是一个简单的出口(如此处所示),通常最好将出口编码到循环本身中。
while (true): if reasonneeded(i) break i = i+1
应该可以吗?