Python:打破多级循环

时间:2014-06-11 18:14:26

标签: python

我有一个Miller-Rabin素数测试器的伪代码:

function isPrime(n, k=5)
    if n < 2 then return False
    for p in [2,3,5,7,11,13,17,19,23,29]
        if n % p == 0 then return n == p
    s, d = 0, n-1
    while d % 2 == 0
        s, d = s+1, d/2
    for i from 0 to k
        x = powerMod(randint(2, n-1), d, n)
        if x == 1 or x == n-1 then next i
        for r from 1 to s
            x = (x * x) % n
            if x == 1 then return False
            if x == n-1 then next i
        return False
    return True

但由于内部next i循环中的for语句必须断开两个循环,因此将其转换为Python很难。 Python中没有goto。在Stack Overflow上提出这个问题的其他提问者被告知要使用returntry/except条件或其他布尔标志的本地函数,但这些解决方案要么不要在这里申请或者会大大改变这个可爱的伪代码。

这个问题的Pythonic方法是什么?

3 个答案:

答案 0 :(得分:3)

我认为pythonic方法是try / except,可读性更喜欢方法或布尔值,但我认为这可以通过添加一行来解决:

    for i in xrange(k):
        x = powerMod(randint(2, n-1), d, n)
        if x == 1 or x == n-1: continue
        for r in xrange(1,s):
            x = (x * x) % n
            if x == 1: return False
            if x == n-1: break #*
        if x != n-1: #added line
            return False
    return True

打破标有#*的行是有问题的,因为它返回false,但如果我们修复它就像“下一个”。

tobias_k建议的另一个解决方案是使用/ else:

    for i in xrange(k):
        x = powerMod(randint(2, n-1), d, n)
        if x == 1 or x == n-1: continue
        for r in xrange(1,s):
            x = (x * x) % n
            if x == 1: return False
            if x == n-1: break 
        else: #added line
            return False
    return True
如果循环为return False,则不会调用

break语句 - 仅当它已用完时才会被调用。

答案 1 :(得分:1)

您可以将breakcontinuefor: else一起使用。

for i from 0 to k
    x = powerMod(randint(2, n-1), d, n)
    # Use 'continue' to go to next i (skip inner loop).
    if x == 1 or x == n-1 then next i
    for r from 1 to s
        x = (x * x) % n
        if x == 1 then return False
        # Use 'break' to exit this loop and go to next i
        # since this loop is at the end of the i loop.
        if x == n-1 then next i
    else:
        # This is only reached if no `break` occurred
        return False
return True

答案 2 :(得分:0)

Tryexcept在这里可以很好地工作。

class BreakException(Exception):
    pass


try:
    for a in range(4532):
        for b in range(4328):
            for c in range(47328):
                for d in range(5993):
                    if something:
                        raise BreakException
except BreakException:
    pass