在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
答案 0 :(得分:7)
这是将goto带到Python的肮脏黑客。 while 1:
行是标签,continue
语句是goto。
如果可以避免,请不要编写类似的代码。如果必须执行此操作,请至少将其设为while True:
,因为while
的参数通常是布尔值。
答案 1 :(得分:1)
如果您need > room && keys == True
转到continue
,则会重新触发while
循环而不会break
。这看起来很丑陋,但在这种情况下是必要的(当然应该有替代方案)。