有几种方法可以打破几个嵌套循环
他们是:
1)使用break-continue
for x in xrange(10):
for y in xrange(10):
print x*y
if x*y > 50:
break
else:
continue # only executed if break was not used
break
2)使用return
def foo():
for x in range(10):
for y in range(10):
print x*y
if x*y > 50:
return
foo()
3)使用特殊例外
class BreakIt(Exception): pass
try:
for x in range(10):
for y in range(10):
print x*y
if x*y > 50:
raise BreakIt
except BreakIt:
pass
我有一些想法可能还有其他方法可以做到这一点。 它是通过使用StopIteration异常直接发送到外部循环的。 我写了这段代码
it = iter(range(10))
for i in it:
for j in range(10):
if i*j == 20:
raise StopIteration
不幸的是,StopIteration还没有被任何for循环捕获,并且该代码产生了一个丑陋的Traceback。 我认为这是因为StopIteration不是从迭代器它内部发送的。 (这是我的猜测,我不确定)。
有什么方法可以将StopIteration发送到外部循环?
谢谢!
答案 0 :(得分:4)
您希望破坏的嵌套循环的另一种方法是折叠它们。像
这样的东西for x, y in ((x, y) for x in range(10) for y in range(10)):
print x*y
if x*y > 50: break
答案 1 :(得分:4)
你可以用协同程序做这样的事情:
def stoppable_iter(iterable):
it = iter(iterable)
for v in it:
x = yield v
if x:
yield
return
然后像这样使用它:
it = stoppable_iter(range(10))
for i in it:
for j in range(10):
print i, j
if i*j == 20:
it.send(StopIteration) # or any value that evaluates as True
break
以及它如何运作的简短例子:
>>> t = stoppable_iter(range(10))
>>> t.next()
0
>>> t.next()
1
>>> t.send(StopIteration)
>>> t.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
答案 2 :(得分:1)
我认为这是因为
StopIteration
不是从迭代器it
内部发送的。 (这是我的猜测,我不确定)。
完全正确。
有什么方法可以将
StopIteration
发送到另一个循环吗?
与#3相同,除了使用StopIteration
而不是您定义的例外。无论如何,这是一个很好用的。
在评论中我提到编写一个迭代器,可以告诉他下次循环时提升StopIteration。这是我正在谈论的那种事情:
class StoppableIterator(object):
def __init__(self, iterable):
self._iter = iter(iterable)
self._stop = False
def __iter__(self):
return self
def stop(self):
self._stop = True
def next(self):
if self._stop:
raise StopIteration
return next(self._iter)
用法:
si = StoppableIterator([2, 3, 5, 7, 11, 13])
for i in si:
for j in xrange(i):
print i, j
if j == 7:
si.stop() # will break out of outer loop next iteration
break # breaks out of inner loop
答案 3 :(得分:1)
你可以使用.close
,这是自Python 2.5以来每个生成器都有的:
代码在Python 3.2中,但它也应该在2.x中工作。
在Python 2.x中,我使用xrange
代替range
。
outer_loop_iterator = (i for i in range(10)) #we need named generator
for x in outer_loop_iterator:
for y in range(10):
print(x*y)
if x*y > 50:
outer_loop_iterator.close()
break #I'm affraid that without this inner loop could still work