我需要生成三个自然数,它们的和是n。第一个数字可以是最大x,第二个数字可以是最大y,最后一个数字可以是最大z。目前我正在做这件事
def f(n):
return [(i, j, k)
for i in range(x+1)
for j in range(y+1)
for k in range(z+1)
if i + j + k == n]但是n很大,在500和x, y, z附近都不到200。目前,我有3个变量(i, j, k)从3个范围生成。在列表理解中使用两个循环可以做到这一点吗?
发布于 2015-07-10 17:40:53
是啊,
您可以只计算第三个数字,并检查它是否在正确的范围内(Martijn♦)。
[(i, j, n - i - j) for i in range(x+1) for j in range(y+1) if 0 <= n - i - j <= z]发布于 2015-07-10 17:52:56
您需要做的是根据第一个变量(j)的值约束第二个变量(i),并根据两个第一个变量约束最后一个变量(k):
l = []
for i in range(1, x + 1):
for j in range(max(1, n - x - z), min(y + 1, n - x - 1)): # No need to go above n - x - 1or bellow n - x - z
# For k, you do not even need a loop since it is constrained by i and j
k = n - i - j
if 0 < k <= z:
l.append((i, j, k))我没有使用列表压缩来详细说明代码,但您当然可以:
[(i, j, n - i - j) for i in range(1, x + 1) for j in range(max(1, n - x - z), min(y + 1, n - x - 1)) if 0 < n - i - j <= z]当x等于1 (全局循环中的第一个值)时,y的范围从n - x - z = 500 - 1 - 200 = 299到200,也就是说,您甚至不需要进入y循环,这是正常的,因为您需要x至少为100才能到达500 (因为<代码>D14和<代码>D15至多是<代码>D16)。
每次你面对这类问题时,想想“如何根据已经赋值的变量减少当前变量的域?”
顺便说一句,执行k = n - i - j赋值等同于对大小为0或1的范围进行循环,如下所示:
for k in range(max(1, n - i - j), min(z + 1, n - i - j + 1)):
l.append((i, j, k))请注意,在这种情况下,您不必再检查0 < k <= z。
https://stackoverflow.com/questions/31337478
复制相似问题