在 Python 中使用 "while 1, do something, break" 有什么理由吗?
Any reason to use "while 1, do something, break" in Python?
在 Python 库中 SymPy I try to understand the function partitions()
in sympy.utilities.iterables
:
它是这样开始的:
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
在 need > room && keys == True
的情况下,您转到 continue
,re-fires while
循环而不是 break
它。这看起来很丑陋,但在这种情况下是必要的(当然应该有替代方案)。
这是将 goto 带到 Python 的肮脏黑客。 while 1:
行是标签,continue
语句是转到。
如果可以避免,请不要编写这样的代码。如果你必须这样做,至少要做到while True:
,因为while
的参数通常是一个布尔值。
在 Python 库中 SymPy I try to understand the function partitions()
in sympy.utilities.iterables
:
它是这样开始的:
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
在 need > room && keys == True
的情况下,您转到 continue
,re-fires while
循环而不是 break
它。这看起来很丑陋,但在这种情况下是必要的(当然应该有替代方案)。
这是将 goto 带到 Python 的肮脏黑客。 while 1:
行是标签,continue
语句是转到。
如果可以避免,请不要编写这样的代码。如果你必须这样做,至少要做到while True:
,因为while
的参数通常是一个布尔值。