将列表分成两个,使子列表的总和相等

时间:2018-09-16 07:40:14

标签: python

假设有一个列表L=list(range(N)),编号为n1n2,其中n1+n2=sum(L)。 我想定义一个将L分为L1L2的函数,以便sum(L1)=n1sum(L2)=n2

如何有效构建此功能?

示例:

给出:N = 7,n1 = 7,n2 = 14

我们得到了:L = list(range(7))

我们需要func(L)返回[3,4]和[0,1,2,5,6]

2 个答案:

答案 0 :(得分:2)

这将为您提供满足条件的所有可能组合:

def fit_sum(l, s):
    for i, n in enumerate(l):
        if n == s:
            yield frozenset([n])
        elif n < s:
            for r in fit_sum(l[:i] + l[i+1:], s - n):
                yield frozenset([n, *r])

def func(N, n1, n2):
    L = list(range(N))
    for r in set(fit_sum(L, n1)):
        yield list(r), list(set(L) - r)

for L1, L2 in func(7, 7, 14):
    print('{}, {}'.format(L1, L2))

这将输出:

[0, 3, 4], [1, 2, 5, 6]
[3, 4], [0, 1, 2, 5, 6]
[1, 2, 4], [0, 3, 5, 6]
[0, 2, 5], [1, 3, 4, 6]
[2, 5], [0, 1, 3, 4, 6]
[1, 6], [0, 2, 3, 4, 5]
[0, 1, 6], [2, 3, 4, 5]
[0, 1, 2, 4], [3, 5, 6]

答案 1 :(得分:0)

@ adam-smith的解决方案是正确的,但是有两个相同的错误。

另外,请注意,您应使用小写字母表示 变量,例如列表。

def split_list(l, n1, n2):
    l1, l2 = [], []  # new lists
    x = max(n1, n2)
    for n in reversed(l):
        if n <= x:
            l1.append(n)
            x -= n
        else:
            l2.append(n)
    if n1 < n2:
        l2, l1 = l1, l2

    assert sum(l1) == n1, sum(l1)        
    assert sum(l2) == n2, sum(l2)
    return l1, l2