Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 生成与参数N相加的列表的乘积_Python - Fatal编程技术网

Python 生成与参数N相加的列表的乘积

Python 生成与参数N相加的列表的乘积,python,Python,我正在寻找一种快速方法来生成值为0到(包括)N的乘积,其总和为N。对于更简单的问题,如下所示 N = 10 output = [] for i in xrange(N+1): for j in xrange(N+1-i): for k in xrange(N+1-i-j): output.append([i,j,k]) 因此,在本例中,输出应该只包含长度为3的列表。近似 [v for v in itertools.product(*[rang

我正在寻找一种快速方法来生成值为0到(包括)
N
的乘积,其总和为
N
。对于更简单的问题,如下所示

N = 10
output = []
for i in xrange(N+1):
    for j in xrange(N+1-i):
        for k in xrange(N+1-i-j):
           output.append([i,j,k])   
因此,在本例中,输出应该只包含长度为3的列表。近似

[v for v in itertools.product(*[range(N+1) for i in range(3)]) if sum(v) == N)]
编辑:正如Joran所指出的,上面的行没有利用第三个元素始终是“rest”这一事实,即
N-i-j

希望有一种方法可以在不评估每种可能产品的结果的情况下使用itertools实现这一点。目前,我有一个递归函数,除了一些效率问题(例如经常调用
len
)外,它还需要相当长的时间来处理较大的max\u深度:

def recursive_expand(input_list, max_sum, max_depth):
    ''' Creates list of lists of integers, where elements of each 
        sub_list sum to max_sum.
    '''
    # If current elements already sum to max_sum
    if max_sum == 0:
        return [input_list + [0] * (max_depth - len(input_list))]
    # If the list can only contain one more element
    elif len(input_list) == max_depth - 1:
        return [input_list + [max_sum]]

    output_lists = []
    for n in xrange(max_sum + 1):
        output_lists.extend( \
                 recursive_expand(input_list + [n], max_sum - n,max_depth))
    return output_lists

>>> foo = recursive_expand([], 2, 3)
>>> print np.array(foo)
[[0 0 2]
 [0 1 1]
 [0 2 0]
 [1 0 1]
 [1 1 0]
 [2 0 0]]
编辑2:要归功于jonrsharpe,此函数生成长度为
k
的元组,其中包含从
start
n
的整数,求和到
n
,排序很重要。如果排序不重要,请查看他的答案(因为排序更有效)


而且,在这里可以找到查找整数分区(之后可以用零填充)的最有效的实现:

好的,我将在这里讨论一个问题,并猜测您想要3个值,它们的总和为某个神奇值N,同时还满足一些附加约束

您不需要计算所有3个值

a + b +c = N  ==> c = N - a -b
您可以计算2个值并求解第3个值

for a in range(N): #unless the other 2 values can be 0 you dont really need to go all the way to n
    for b in range(a,N):  #this assumes that b >= a
         c = N - a - b
         if some_constraint(a,b,c,N):
                my_list.append([a,b,c])

老实说,我不知道这是否回答了您的问题,但这似乎是您的问题的方向…

如果您对订单不感兴趣(也就是说,你总是想要
x哈哈,你是对的。我忘了在简化的场景中这么做。底部的函数确实利用了这一点。不过,我正在寻找一个推广;如果我们有k值而不是3,那会怎么样?你只是在寻找一种快速的计算方法吗?在那之后,你似乎只需要填充w用零和置换。我是。但我不知道它的术语。谢谢,这使得搜索高效算法变得更容易。很好!不过,我确实关心排序。你有我的投票权,如果我能让它工作,我会接受它作为答案(并编辑我的问题)!
for a in range(N): #unless the other 2 values can be 0 you dont really need to go all the way to n
    for b in range(a,N):  #this assumes that b >= a
         c = N - a - b
         if some_constraint(a,b,c,N):
                my_list.append([a,b,c])
def sets(n):
    for x in xrange(1, (n // 3) + 1):
       for y in xrange(x, ((n - x) // 2) + 1):
           yield x, y, n - (x + y)
list(sets(10)) == [(1, 1, 8), (1, 2, 7), (1, 3, 6), (1, 4, 5), 
                   (2, 2, 6), (2, 3, 5), (2, 4, 4), (3, 3, 4)]
def sets_2(n, k=3, s=1):
    for x in range(s, (n // k) + 1):
        if k == 2:
            yield x, n - x
        else:
            for s in sets_2(n - x, k - 1, x):
                yield (x, ) + s
list(sets_2(10, 2)) == [(1, 9), (2, 8), (3, 7), (4, 6), (5, 5)]

list(sets_2(10, 4)) == [(1, 1, 1, 7), (1, 1, 2, 6), (1, 1, 3, 5), 
                        (1, 1, 4, 4), (1, 2, 2, 5), (1, 2, 3, 4), 
                        (1, 3, 3, 3), (2, 2, 2, 4), (2, 2, 3, 3)]
list(sets_2(10, 3, 0)) == [(0, 0, 10), (0, 1, 9), (0, 2, 8), (0, 3, 7), 
                           (0, 4, 6), (0, 5, 5), (1, 1, 8), (1, 2, 7), 
                           (1, 3, 6), (1, 4, 5), (2, 2, 6), (2, 3, 5), 
                           (2, 4, 4), (3, 3, 4)]