Python:打破多级循环

Python:打破多级循环,python,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

我有一个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
函数isPrime(n,k=5)
如果n<2,则返回False
对于[2,3,5,7,11,13,17,19,23,29]中的p
如果n%p==0,则返回n==p
s、 d=0,n-1
而d%2==0
s、 d=s+1,d/2
对于从0到k的i
x=powerMod(randint(2,n-1),d,n)
如果x==1或x==n-1,则下一个i
对于从1到s的r
x=(x*x)%n
如果x==1,则返回False
如果x==n-1,则下一个i
返回错误
返回真值
但是将其转换为Python很困难,因为内部
for
循环中的
next i
语句必须中断两个循环。Python中没有
goto
。关于堆栈溢出问题的其他提问者被告知使用带有
返回
、或
尝试/例外
条件或附加布尔标志的局部函数,但这些解决方案要么不适用于这里,要么会使这段伪代码非常丑陋


什么是Pythonic方法解决这个问题?

我认为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,但是如果我们修复它,它就像“next i”

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
-ed,则不会调用该语句-仅当循环已耗尽时才调用该语句。

您可以使用
break
continue
为: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

@Christian“我有这个伪代码”这应该不是有效的python。你反对
for:else
范式吗?这可能对你有用,但如果“不丑”是你的标准,你可能也不想这样。你可能想澄清,你不想打破两个循环,而是打破第一个循环,继续第二个循环。(如果你在下一个i中的第二个i中中断,那么你在不应该的时候返回False。)@TalKremerman这是怎么回事?return语句在到达时将跳出循环,因此这无关紧要。如果
x==n-1
您应该转到下一个i。如果你只是
break
,你就达到了
return False
,你不应该这样做。我认为这是一种情况,你可以使用它来代替新的
,如果
根本不需要的话!这就是我发表评论的原因!;-)顺便说一句,我认为在Python中,
powerMod
就是
pow
(使用可选的第三个参数。至少测试看起来是这样的。我使用了较小的格式,所以保持原样。我个人认为,
如果xxx:yyyy
行的可读性较低,所以我也不会使用它,但我希望尽可能少地更改原始代码。我不喜欢第一种方法,因为重复测试。我确实喜欢第二种方法,它非常地道。谢谢Tal和Tobias!