有什么理由在Python中使用“while 1,do something,break”?

时间:2016-01-13 00:38:18

标签: python while-loop sympy

在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 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 个答案:

答案 0 :(得分:7)

这是将goto带到Python的肮脏黑客。 while 1:行是标签,continue语句是goto。

如果可以避免,请不要编写类似的代码。如果必须执行此操作,请至少将其设为while True:,因为while的参数通常是布尔值。

答案 1 :(得分:1)

如果您need > room && keys == True转到continue,则会重新触发while循环而不会break。这看起来很丑陋,但在这种情况下是必要的(当然应该有替代方案)。