在Python中使用“while 1,do something,break”的原因是什么?

5
在Python库SymPy中,我试图理解sympy.utilities.iterables中的partitions()函数:

它开头是这样的:

def partitions(n, m=None, k=None, size=False):
    """Generate all partitions of integer n (>= 0).

我对下面的while循环感到困惑,因为它看起来毫无意义。如果我去掉while 1:break应该不会有任何影响。但是,我认为开发SymPy的人知道自己在做什么,并不会犯非常简单的错误。所以这个while循环有一些我没有看到的意义吗?
while 1:
    # Let i be the smallest key larger than 1.  Reuse one instance of i.
    i = keys[-1]
    newcount = ms[i] = ms[i] - 1
    reuse += i
    if newcount == 0:
        del keys[-1], ms[i]
    room += 1

    # Break the remainder into pieces of size i-1.
    i -= 1
    q, r = divmod(reuse, i)
    need = q + bool(r)
    if need > room:
        if not keys:
            return
        continue

    ms[i] = q
    keys.append(i)
    if r:
        ms[r] = 1
        keys.append(r)
    break

出于学习目的,我简化了整个函数,my_partitions(n) 提供与 partitions(n) 相同的结果。

def my_partitions(n):
    ms = {n: 1}
    keys = [n]
    yield ms

    while keys != [1]:
        # Reuse any 1's.
        if keys[-1] == 1:
            del keys[-1]
            reuse = ms.pop(1)
        else:
            reuse = 0

        # Let i be the smallest key larger than 1.  Reuse one instance of i.
        i = keys[-1]
        ms[i] -= 1
        reuse += i
        if ms[i] == 0:
            del keys[-1], ms[i]

        # Break the remainder into pieces of size i-1.
        i -= 1
        q, r = divmod(reuse, i)
        ms[i] = q
        keys.append(i)
        if r:
            ms[r] = 1
            keys.append(r)

        yield ms

2
虽然这段代码看起来很丑,但它的原因是当“need > room”时需要使用“continue”的情况。 - Chad S.
欢迎提交拉取请求来清理这个问题。SymPy测试套件中有针对此函数的测试,因此如果您的实现有误,应该很明显。 - asmeurer
显然,my_partitions(n)不仅仅是对partitions(n, m, k, size)的清理。它只是为相同的n提供相同的结果。 - Watchduck
2个回答

8
这是一种将goto引入Python的不良hack。while 1:行是标签,continue语句是goto。
如果可以避免,请不要编写此类代码。 如果你必须这样做,至少要将其改为while True:,因为while的参数通常是布尔值。

这可能是从Knuth的翻译。 - asmeurer
不错的观点。如果我想理解SymPy之类的东西,我应该花一些时间研究TAOCP。 - Watchduck

1
need > room && keys == True的情况下,您需要使用continue,它会重新启动while循环而不是break。这看起来相当丑陋,但在这种情况下是必要的(当然还应该有其他替代方案)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接