7

いくつかのネストされたループから抜け出す方法はいくつかあります

彼らです:

1) ブレークコンティニューを使用する

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 を生成しました。iterator itの内部から StopIteration が送信されなかったことが原因だと思います。(これは私の推測であり、よくわかりません)。

StopIteration を外側のループに送信する方法はありますか?

ありがとう!

4

4 に答える 4

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
于 2011-08-03T00:21:12.123 に答える
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
于 2011-08-03T00:33:02.803 に答える
1

StopIterationiterator の内部から送信されていないためだと思いますit。(これは私の推測であり、よくわかりません)。

その通りです。

StopIteration他のループに送信できる方法はありますか?

StopIteration定義した例外の代わりに使用することを除いて、#3と同じ方法。とにかく使い勝手が良いです。

コメントの中で、次回のループで 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
于 2011-08-03T00:15:48.943 に答える